2013-06-27 9 views
9

Używam EF 6 async odpytywanie funkcji, takich jakSqlDependency z EntityFramework 6 (asynchroniczny)

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

Chcę także rozpocząć zależności SQL na te pytania tak, że mogę otrzymywać powiadomienia, gdy dane w zmiany w bazie danych. Można to zrobić za pomocą System.Runtime.Remoting.Messaging.CallContext następująco:

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

.. i to działa dobrze. Ale pojawia się problem, jeśli chcę mieć SqlDependency na więcej niż jednym zapytaniu. Jeśli mam dwie metody podobne do powyższej async podobną do GetData(), a tylko ja wykonuję obie jednocześnie, tylko pierwsza otrzyma powiadomienie o zmianie. Zakładam, że dzieje się tak z powodu CallContext, w którym plik cookie jest ustawiany przez każdą z metod. Jeśli poczekam na zakończenie pierwszej metody async, a następnie zadzwonię po drugiej, otrzymają powiadomienia o zmianach zgodnie z oczekiwaniami. Czy jest jakieś rozwiązanie tego problemu?

Odpowiedz

8

Nie jestem zbyt zaznajomiony z SqlDependency, ale poniższe informacje pozwolą Twojemu CallContext mieć poprawną wartość w momencie wywołania ToListAsync (gdy uruchomionych jest wiele połączeń). Dowód koncepcji tutaj, 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; 
     } 
    } 
Powiązane problemy