2013-06-27 14 views
9

sto usando l'EF 6 async caratteristiche interrogazione, come ad esempioSqlDependency con EntityFramework 6 (asincrona)

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

voglio iniziare anche le dipendenze SQL su queste query in modo che possa essere avvisato quando i dati in il database cambia. Posso farlo utilizzando la System.Runtime.Remoting.Messaging.CallContext come segue:

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

.. e funziona benissimo. Ma mi sto imbattendo in un problema se voglio avere un SqlDependency su più di una query. Se ho due metodi async simili a GetData() sopra, e corro entrambi nello stesso momento, solo il primo riceverà notifiche di modifica. Suppongo che ciò sia dovuto al fatto che CallContext abbia il cookie impostato da ciascun metodo in successione. Se aspetto che venga completato il primo metodo async, quindi chiami il secondo, entrambi ricevono le notifiche di modifica come previsto. c'è qualche soluzione a questo?

risposta

8

Non ho molta familiarità con SqlDependency, ma il seguente consentirà a CallContext di avere il valore corretto al momento in cui viene chiamato ToListAsync (quando sono in esecuzione più chiamate). Prova di concetto qui, 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; 
     } 
    }