2008-09-01 8 views
32

Wir haben gerade begonnen, LINQ to SQL bei der Arbeit für unsere DAL & wir haben nicht wirklich einen Standard für Out-Caching-Modell. Zuvor hatten wir eine Basisklasse "DAL" verwendet, die eine Cache-Manager-Eigenschaft implementierte, von der alle unsere DAL-Klassen geerbt wurden, aber jetzt haben wir diese nicht. Ich frage mich, ob jemand einen Standardansatz zum Zwischenspeichern von LINQ to SQL-Ergebnissen entwickelt hat?Wie implementieren Sie das Caching in Linq to SQL?

Wir arbeiten in einer Web-Umgebung (IIS), wenn das einen Unterschied macht. Ich weiß, dass dies am Ende eine subjective Frage sein könnte, aber ich denke immer noch, dass die Info wertvoll wäre.

EDIT: Um zu verdeutlichen, ich spreche nicht über Caching ein einzelnes Ergebnis, ich bin nach mehr einer Architektur-Lösung, wie in, wie Sie Caching einrichten, so dass alle Ihre Link-Methoden die gleiche Zwischenspeicherung verwenden die Architektur.

Antwort

9

Eine schnelle Antwort: Verwenden Sie das Repository-Muster (siehe Domain Driven Design von Evans), um Ihre Entitäten abzurufen. Jedes Repository speichert die Dinge, die es enthält, im Cache, idealerweise indem jede Instanz des Repositorys auf einen Singleton-Cache zugreifen kann (jeder Thread/jede Anfrage wird ein neues Repository instanziieren, aber es kann nur einen Cache geben).

Die obige Antwort funktioniert nur auf einer Maschine. Verwenden Sie memcached als Ihre Caching-Lösung, um das auf vielen Computern zu verwenden. Viel Glück!

+7

Beachten Sie, dass dieser Ansatz nicht wirklich viel mit LINQ oder LINQ to SQL zu tun hat. Repository-basierte APIs sind nicht mit weiteren LINQ-Abfragen kombinierbar. –

+1

Sie sollten die Objektverfolgung deaktivieren, wenn Sie das Repository-Muster verwenden. Andernfalls wird dies im Ermessen des Repository brechen: 'repository.Get (1) .ReferencedTable.Id' ... seit" .ReferencedTable "wird schwer für die zwischengespeicherte Liste nachschlagen ohne einen Kontext. – bzlm

3

Es ist direkt unter die Nase:

List<TableItem> myResult = (from t in db.Table select t).ToList(); 

nun nur Cache MyResult wie Sie Ihre alten DAL die zurückgegebenen Daten zwischengespeichert haben würde.

38

Meine LINQ query result cache ist wahrscheinlich genau das, wonach Sie suchen.

var q = from c in context.Customers 
     where c.City == "London" 
     select new { c.Name, c.Phone }; 

var result = q.Take(10).FromCache(); 

Pete.

+4

Das ist ein brillanter Code, so etwas muss in das Framework eingebaut werden. – PeteT

+0

Es ist 2017 und ich suchte nach einer ähnlichen Lösung und fand dieses https://github.com/zzzprojects/EntityFramework-Plus Projekt –

1

Ich fand this post, die eine Erweiterungsmethode als Mittel zum Zwischenspeichern der LINQ-Objekte bietet.

Ich habe für weaks meinen Kopf gegen die Wand hämmern wurde nun eine gute Caching-Lösung für Linq2SQL, um herauszufinden, muss ein zugeben, dass ich wirklich kämpfen, um eine one-size zu finden, passt zu ...

Das Repository-Muster neigt dazu, die Nützlichkeit von Linq einzuschränken, da das Caching (ohne Neuimplementierung von IQueryable) außerhalb der Linq-Anweisung ausgeführt werden muss.

Darüber hinaus sind verzögertes Laden und Objektverfolgung beide große No-Nos, wenn Sie Ihre Objekte zwischenspeichern, was die Aktualisierung etwas schwieriger macht.

Wer es geschafft hat, dieses Problem in einem hochgradig gleichzeitigen Webprojekt zu lösen, bitte läuten Sie ein und retten Sie die Welt! :)

1

Ich verstehe, dass dies vielleicht ein bisschen spät Antwort ... Nicht weniger, können Sie versuchen, das LinqToCache Projekt.Es hakt wenn möglich eine SqlDependency für eine beliebige LINQ-Abfrage und bietet eine aktive Cache-Invalidierung über die serverseitigen Abfragebenachrichtigungen. Die Abfragen müssen gültige Abfragen für Benachrichtigungen sein, siehe Creating a Query for Notification. Die meisten Linq-to-SQL-Abfragen entsprechen diesen Einschränkungen, solange die Tabellen unter Verwendung zweiteiliger Namen angegeben werden (dbo.Table, nicht nur Table).

+0

Ich habe ein grundlegendes L2S-Modell mit einer einzigen Tabelle (Request) eingerichtet und ich versuche, LinqToCache für eine grundlegende Abfrage 'from r in ctx.Requests select r' zu verwenden. Bei der Verwendung von SqlDependency ohne Angabe eines Optionswerts muss jedoch SqlDependency.Start() vor der Ausführung eines der SqlDependency-Instanz hinzugefügten Befehls aufgerufen werden. – James

+1

@ James: Call 'SqlDependency.Start()'? –

+0

Mein Fehler, ich dachte dumm 'AsCached' löste' SqlDependency.Start() 'intern aus ... dann erkannte ich, dass das keinen Sinn ergeben würde! Das funktioniert jetzt, danke. Nette Arbeit übrigens, keine Hoffnung auf eine zukünftige Zusammenarbeit mit E2F? – James