具有EntityFramework 6的SqlDependency(异步)
本文关键字:异步 SqlDependency EntityFramework 具有 | 更新日期: 2023-09-27 18:20:07
我正在使用EF 6 async
查询功能,如
var list = await cx.Clients.Where(c => c.FirstName.Length > 0).ToListAsync();
我还想启动这些查询的SQL依赖项,以便在数据库中的数据发生更改时得到通知。我可以使用System.Runtime.Remoting.Messaging.CallContext
如下所示:
async Task GetData()
{
using (ClientsContext context = new ClientsContext()) // subclass of DbContext
{
SqlDependency.Start(context.Database.Connection.ConnectionString);
SqlDependency dependency = new SqlDependency();
dependency.OnChange += (sender, e) =>
{
Console.Write(e.ToString());
};
System.Runtime.Remoting.Messaging.CallContext.SetData("MS.SqlDependencyCookie", dependency.Id);
var list = await context.Clients.Where(c => c.FirstName.Length > 0).ToListAsync();
}
}
而且效果很好。但是,如果我想在多个查询上使用SqlDependency
,就会遇到问题。如果我有两个类似于上面GetData()
的async
方法,并且我同时运行这两个方法,那么只有第一个方法会收到更改通知。我认为这是由于CallContext具有由每个方法连续设置的cookie。如果我等待第一个async
方法完成,然后调用第二个方法,它们都会按预期获得更改通知。有什么解决办法吗?
我对SqlDependency不太熟悉,但以下内容将允许您的CallContext在调用ToListAsync时具有正确的值(当多个调用正在运行时)。这里的概念证明,https://dotnetfiddle.net/F8FnFe
async Task<List<Client>> GetData()
{
using (ClientsContext context = new ClientsContext()) // subclass of DbContext
{
SqlDependency.Start(context.Database.Connection.ConnectionString);
SqlDependency dependency = new SqlDependency();
dependency.OnChange += (sender, e) =>
{
Console.Write(e.ToString());
};
Task<List<Client>> task = Task<Task<List<Client>>>.Factory.StartNew(async () =>
{
System.Runtime.Remoting.Messaging.CallContext.SetData("MS.SqlDependencyCookie", dependency.Id);
var list = await context.Clients.Where(c => c.FirstName.Length > 0).ToListAsync();
}).Unwrap();
return await task;
}
}