2013-06-27 45 views
9

我使用的是EF 6種async查詢功能,如的SqlDependency用的EntityFramework 6(異步)

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,我會遇到問題。如果我有兩個async方法與上面的GetData()類似,並且我同時運行兩個方法,則只有第一個方法會收到更改通知。我認爲這是由於CallContext具有由每種方法相繼設置的cookie。如果我等待第一個方法完成,然後再撥打第二個方法,他們都會按預期收到更改通知。有沒有解決這個問題的方法?

回答

8

我對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; 
     } 
    } 
相關問題