2008-09-01 5 views
32

Nous venons de commencer à utiliser LINQ to SQL au travail pour notre DAL & nous n'avons pas vraiment trouvé de standard pour le modèle de mise en cache. Auparavant, nous utilisions une classe de base 'DAL' qui implémentait une propriété de gestionnaire de cache dont toutes nos classes DAL héritaient, mais maintenant nous ne l'avons pas. Je me demande si quelqu'un a trouvé une approche «standard» pour mettre en cache les résultats LINQ to SQL?Comment implémenter la mise en cache dans Linq to SQL?

Nous travaillons dans un environnement Web (IIS) si cela fait une différence. Je sais que cela pourrait bien finir par être une question de subjective, mais je pense toujours que l'information serait précieuse. Pour clarifier, je ne parle pas de mise en cache d'un résultat individuel, je suis après plus d'une solution d'architecture, comme dans la façon dont vous configurez la mise en cache de sorte que toutes vos méthodes de lien utilisent la même mise en cache architecture.

Répondre

9

Une réponse rapide: Utilisez le modèle de référentiel (voir Conception pilotée par domaine par Evans) pour récupérer vos entités. Chaque référentiel mettra en cache les éléments qu'il conservera, idéalement en laissant chaque instance du référentiel accéder à un cache singleton (chaque thread/requête instanciera un nouveau référentiel mais il ne peut y avoir qu'un seul cache).

La réponse ci-dessus ne fonctionne que sur une machine. Pour pouvoir utiliser cela sur de nombreuses machines, utilisez memcached comme solution de mise en cache. Bonne chance!

+7

Notez que cette approche n'a pas vraiment beaucoup à faire avec LINQ ou LINQ to SQL. Les API basées sur le référentiel ne peuvent pas être composées avec d'autres requêtes LINQ. –

+1

Vous devez désactiver le suivi des objets lorsque vous utilisez le modèle de référentiel. Dans le cas contraire, cela se produira à la discrétion du Repository: 'repository.Get (1) .ReferencedTable.Id' ... puisque" .ReferencedTable "sera difficile pour la liste mise en cache de rechercher sans contexte. – bzlm

3

Il est juste sous votre nez:

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

Maintenant, myResult juste de cache que vous avez mis en cache les données renvoyées de votre ancien DAL.

38

Mon LINQ query result cache est probablement exactement ce que vous cherchez.

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

C'est un morceau de code génial, quelque chose comme ça a besoin de construire dans le cadre. – PeteT

+0

Nous sommes en 2017 et je cherchais une solution similaire et j'ai trouvé ce https://github.com/zzzprojects/EntityFramework-Plus project –

1

J'ai trouvé this post, qui offre une méthode d'extension comme un moyen de mettre en cache les objets LINQ.

J'ai frappais ma tête contre le mur pour weaks essayant maintenant de trouver une bonne solution de mise en cache pour Linq2SQL, un dois admettre que je suis vraiment du mal à trouver une taille unique ...

Le modèle de référentiel tend à limiter l'utilité de Linq, car (sans réimplémentation de IQueryable) la mise en cache doit être effectuée en dehors de l'instruction Linq.

De plus, le chargement différé et le suivi d'objet sont deux grands no-nos si vous souhaitez mettre en cache vos objets, ce qui rend les mises à jour plus délicates.

Toute personne qui a réussi à résoudre ce problème dans la nature au sein d'un projet Web très concurrentiel, s'il vous plaît chimer et sauver le monde! :)

1

Je comprends que c'est peut-être un peu de réponse en retard ... Néanmoins, vous pouvez essayer le projet LinqToCache.Il connecte un SqlDepdency à une requête LINQ arbitraire, si possible, et fournit une invalidation de cache active via les notifications de requête côté serveur. Les requêtes doivent être des requêtes valides pour les notifications, voir Creating a Query for Notification. La plupart des requêtes Linq-to-sql sont conformes à ces restrictions, tant que les tables sont spécifiées en utilisant des noms en deux parties (dbo.Table, et pas seulement Table).

+0

J'ai configuré un modèle L2S de base avec une seule table (Request) et j'essaie d'utiliser LinqToCache pour une requête de base 'from r in ctx.Requests select r'. Cependant, il continue à échouer avec l'exception 'Si vous utilisez SqlDependency sans fournir de valeur d'option, SqlDependency.Start() doit être appelé avant l'exécution d'une commande ajoutée à l'instance SqlDependency. 'Des idées? – James

+1

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

+0

Mon mauvais, j'ai stupidement pensé 'AsCached' déclenchait' SqlDependency.Start() 'en interne ... alors réalisé que cela n'aurait aucun sens! Ça marche maintenant, merci. Beau travail, quel espoir pour E2F de travailler dans le futur? – James