从 sql server 读取数据时检测到自引用循环
Posted
技术标签:
【中文标题】从 sql server 读取数据时检测到自引用循环【英文标题】:Self referencing loop detected while reading data from sql server 【发布时间】:2020-01-07 21:34:42 【问题描述】:我正在尝试使用以下代码每秒从数据库中读取数据:
public class DBChangeService : DelegatingHandler, IHostedService
private Timer _timer;
public SqlDependencyEx _sqlDependency;
private readonly IHubContext<SignalServer> _hubcontext;
private readonly IServiceScopeFactory _scopeFactory;
string connectionString = "";
public IConfiguration Configuration get;
public DBChangeService(IConfiguration configuration, IHubContext<SignalServer> hubcontext, IServiceScopeFactory scopeFactory)
_scopeFactory = scopeFactory;
_hubcontext = hubcontext;
Configuration = configuration;
connectionString = Configuration.GetConnectionString("DefaultConnection");
public Task StartAsync(CancellationToken cancellationToken)
_timer = new Timer(Heartbeat, null, 0, 1000);
return Task.CompletedTask;
public void Heartbeat(object state)
_hubcontext.Clients.All.SendAsync("SBSystemBrodcasting", SBSystemApps());
public async Task<List<SomeModel>> SBSystemApps()
var data = new List<SomeModel>();
using (var scope = _scopeFactory.CreateScope())
using (SqlConnection connection = new SqlConnection(connectionString))
string commandText = @"SELECT
a.name as AppName,
a.state as AppState,
a.created_at as AppCreatedAt,
a.updated_at as AppUpdatedAt,
a.foundation as AppFoundation,
s.name as SpaceName,
o.name as OrgName
FROM
apps as a
INNER JOIN
spaces as s ON a.space_guid = s.space_guid
INNER JOIN
organizations as o ON s.org_guid = o.org_guid
where s.name = 'system' and o.name = 'system' and a.foundation = 2";
try
SqlCommand cmd = new SqlCommand(commandText, connection);
await connection.OpenAsync();
using (DbDataReader reader = await cmd.ExecuteReaderAsync())
while (await reader.ReadAsync())
var sqlresult = new SomeModel
AppName = reader["AppName"].ToString(),
AppState = reader["AppState"].ToString(),
AppCreatedAt = Convert.ToDateTime(reader["AppCreatedAt"]),
AppUpdatedAt = Convert.ToDateTime(reader["AppUpdatedAt"]),
AppFoundation = Convert.ToInt32(reader["AppFoundation"]),
SpaceName = reader["SpaceName"].ToString(),
OrgName = reader["OrgName"].ToString(),
;
data.Add(sqlresult);
finally
connection.Close();
return data;
public Task StopAsync(CancellationToken cancellationToken)
//Timer does not have a stop.
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
出现以下错误:
Newtonsoft.Json.JsonSerializationException:自引用循环 检测到具有类型的属性“任务” 'System.Runtime.CompilerServices.AsyncTaskMethodBuilder
1+AsyncStateMachineBox
1[System.Collections.Generic.List`1[TestApp.Models.SomeModel],TestApp.Services.DBChangeService+d__11]'。
我已经尝试了在 *** 上可以找到的几乎所有可能的解决方案,但没有一个有效
在启动中:
services.AddMvc().AddJsonOptions(options =>
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
);
在我的班级标题上,我尝试使用[JsonObject(IsReference = true)]
,但没有任何想法适合我?
型号:
[JsonObject(IsReference = true)]
public partial class SomeModel
public string AppName get; set;
public string AppState get; set;
public DateTime AppCreatedAt get; set;
public DateTime AppUpdatedAt get; set;
public int AppFoundation get; set;
public string OrgName get; set;
public string SpaceName get; set;
【问题讨论】:
如果 JSON.Net 抛出错误(以及那个特定的错误),那么很可能是您的模型并且与其余部分有 0 关系。我没有看到它的猜测是你在两个类之间有一个循环引用,这让它很头疼。删除不相关的代码并发布模型。 【参考方案1】:_hubcontext.Clients.All.SendAsync("SBSystemBrodcasting", SBSystemApps());
问题是您使用Task
调用SendAsync
。这不是 API 的设计用途。您应该通过您想要使用的实际有效负载。
有多种方法可以解决这个问题。一种是使用:
_hubcontext.Clients.All.SendAsync("SBSystemBrodcasting", SBSystemApps().GetAwaiter().GetResult());
虽然我建议阅读 this guidance 了解为什么这不是一个好主意。
另一种方法是更改 SBSystemApps
使其同步(即返回 List<T>
而不是 Task<List<T>>
。
【讨论】:
以上是关于从 sql server 读取数据时检测到自引用循环的主要内容,如果未能解决你的问题,请参考以下文章
sql server 2005数据库检索时,出现无法为此请求检索数据的问题