2016-07-27 12 views
0

Ich konvertiere eine SQL-Funktion in C# mit Entity Framework, und die Funktion, die ich konvertiere verwendet den NOLOCK Hinweis für jede Tabelle (10 von ihnen) verbunden wird.Entity Framework Joins mit NOLOCK

Aus diesem Grund habe ich beschlossen, IsolationLevel auf für die gesamte Transaktion festzulegen. Momentan mache ich so interne Joins.

from a in context.table1.ToList() 
join b in context.table2.ToList on a.Id equals b.Id 

so weiter und so fort

Would erklärt Listen, zum Beispiel

IEnumerable<table1> Table1 = new List<table1>(); 

und bevölkern sie dann den Kontext verwenden, bevor ich meine Abfrage führen zu unterschiedlichen Ergebnissen in diesen Tabellen beginnen? I.e wäre Table1 das gleiche wie context.table1.ToList()? Und wenn ja, mit welcher Implementierung sollte ich gehen?

Antwort

2
from a in context.table1.ToList() 
join b in context.table2.ToList on a.Id equals b.Id 

Diese Aussage werden alle Elemente in table1 in den Speicher, alle Elemente in Tabelle2 Speicher materialisieren und dann für den Rest der Abfrage im Speicher verbinden. Tun Sie das nicht, es sei denn, Sie interessieren sich überhaupt nicht für die Leistung. Entfernen Sie stattdessen die ToList-Aufrufe und schließen Sie sich so an.

from a in context.table1 
join b in context.table2 on a.Id equals b.Id 

Das würde einen Beitritt in SQL-Server ergeben und jetzt können Sie mit dem Rest der Abfrage in Linq fortfahren. Die Abfrage würde dann die Ergebnisse aus der Datenbank materialisieren, sobald Sie mit der Iteration über die Ergebnisse beginnen oder eine Erweiterungsmethode ToList, ToArray, AsEnumerable oder eine der anderen Methoden verwenden, die ein einzelnes Element wie Single oder First usw. abruft () Versionen sind auch hier impliziert).


Zweitens ich mit NOLOCK nicht empfehlen, können Sie unerwartete Ergebnisse, die, wenn Sie für eine Tatsache wissen, Pop-up, dass falsche Daten ist keine große Sache, wie vielleicht flüchtige Daten, die zeigen, wo keine Entscheidungen über die unternommen werden, um Daten. Wenn Sie das nicht stört und Sie immer noch das Äquivalent von NOLOCK verwenden möchten, erstellen Sie eine neue Transaktion für Ihre EF-Aufrufe.

using (new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted })) 
{ 
    using (var context = new MyDbContext()) 
    { 
     var result = from a in context.table1 
      join b in context.table2 on a.Id equals b.Id 
      // rest of your linq query here. 

    } 
} 
+0

Ich weiß nicht, ob ich es jemals verwenden würde, aber gibt es eine Möglichkeit, es pro Tabelle zu tun? – adam0101

+1

Nein, es würde einige zusätzliche Logik in Ihrem DbContext benötigen, um die Abfrage zu ändern, die an den Server gesendet wird. Sie könnten eine Ansicht mit NOLOCK-Hinweisen erstellen und diese Ansicht einer Entität in IF zuordnen, dann abstrahieren Sie die NOLOCK-Hinweise aus Ihrem C# -Code alle zusammen. – Igor

+0

Ich konvertiere diese für meinen Job, die SPs, die ich bisher konvertiert habe, waren viel einfacher. Mein Instinkt sagt mir, dass ich NOLOCK nicht in Frage stellen soll, da das momentan über meinem Gehaltsniveau liegt. Danke für den Tipp, ToList() loszuwerden. –