2013-06-27 28 views
9

Tôi đang sử dụng EF 6 async tính năng truy vấn, chẳng hạn nhưSqlDependency với EntityFramework 6 (async)

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

Tôi muốn cũng bắt đầu phụ thuộc SQL trên các truy vấn này để tôi có thể nhận được thông báo khi dữ liệu trong thay đổi cơ sở dữ liệu. Tôi có thể thực hiện việc này bằng cách sử dụng System.Runtime.Remoting.Messaging.CallContext như sau:

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

.. và nó hoạt động tốt. Nhưng tôi đang gặp sự cố nếu tôi muốn có một số SqlDependency trên nhiều truy vấn. Nếu tôi có hai phương pháp async tương tự như GetData() ở trên và tôi chạy cả hai cùng một lúc, chỉ người đầu tiên sẽ nhận được thông báo thay đổi. Tôi cho rằng điều này là do CallContext có cookie được thiết lập bởi từng phương pháp liên tiếp. Nếu tôi đợi phương thức async đầu tiên hoàn thành, sau đó gọi phương thức thứ hai, cả hai đều nhận được thông báo thay đổi như mong đợi. Có giải pháp nào cho điều này không?

Trả lời

8

Tôi không quá quen thuộc với SqlDependency, nhưng bên dưới sẽ cho phép CallContext của bạn có giá trị chính xác tại thời điểm ToListAsync được gọi (Khi nhiều cuộc gọi đang chạy). Bằng chứng về khái niệm ở đây, 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; 
     } 
    } 
Các vấn đề liên quan