SqlDependency with EntityFramework 6 (async)

核能气质少年 提交于 2019-11-29 02:54:27

问题


I'm using the EF 6 async querying features, such as

var list = await cx.Clients.Where(c => c.FirstName.Length > 0).ToListAsync();

I want to also start SQL dependencies on these queries so that I can get notified when the data in the database changes. I can do this using the System.Runtime.Remoting.Messaging.CallContext as follows:

    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();
        }
    }

.. and it works fine. But I am running into an issue if I want to have an SqlDependency on more than one query. If I have two async methods similar to GetData() above, and I run both at the same time, only the first one will get change notifications. I assume that this is due to the CallContext having the cookie set by each method in succession. If I wait for the first async method to complete, then call the second, they both get change notifications as expected. Is there any solution to this?


回答1:


I'm not too familiar with SqlDependency, but the below will allow your CallContext to have the correct value at the time ToListAsync is called (When multiple calls are running). Proof of concept here, 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;
        }
    }


来源:https://stackoverflow.com/questions/17334935/sqldependency-with-entityframework-6-async

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!