2010-10-11 12 views
6

Mon projet (couche d'interface utilisateur est asp.mvc) a été développé à l'aide de .NET 3.5. Après la mise à niveau 4.0 .NET J'ai problème obtenu avec des requêtes compilées:Problème de requête compilé avec DataContext avec .NET 4

[ArgumentException: Query was compiled for a different mapping source than the one associated with the specified DataContext.] 
    System.Data.Linq.CompiledQuery.ExecuteQuery(DataContext context, Object[] args) +863348 
    System.Data.Linq.CompiledQuery.Invoke(TArg0 arg0, TArg1 arg1) +110 

Chaque fois que je lance ma requête je passe mon contexte

return StaticQueries.getTopFiveOrders(mContext, int howMany); 


public static Func<Mycontext, int, IQueryable<Order>> getTopFiveOrders 
      = CompiledQuery.Compile 
       ((Mycontext mContext, int howMany) => 
       (some query).Distinct()); 

L'erreur se produit sur la deuxième demande.

Répondre

4

Cela est dû à un changement dans la façon dont les requêtes compilées fonctionnent.

Ils doivent maintenant être exécutés toujours dans le même contexte.

This Microsoft connect page explique pourquoi le changement a été fait:

Le problème dans ce cas est causé par le fait que CompiledQuery exige la même source de mappage à utiliser pour toutes les exécutions. Dans l'exemple de code que vous utilisez pour reproduire le problème, les différentes instances du DataContext utilisent une nouvelle source de mappage à chaque fois, mais la requête ne parvient pas à le signaler et échoue silencieusement. Si vous utilisez la propriété DataContext.Log ou une autre journalisation comme SQL Server Profiler, vous verrez que la deuxième UPDATE n'est même pas envoyée au serveur.

Cela a été corrigé dans .NET Framework 4.0 de sorte qu'une exception est signalée qui contiendra un message du type "La requête a été compilée pour une autre source de mappage que celle associée au DataContext spécifié". juste échouer silencieusement. Toutefois, le code que vous avez fourni qui fonctionne est la manière correcte de le faire, car il utilise la même source de mappage statique pour toutes les instances de LinqTestDataContext.

Fondamentalement, il a toujours été un problème, mais utilisé à l'échec en silence, ils ont juste fait l'échec explicite dans .NET 4.

0

J'ai aussi fait face au même problème. J'ai enlevé le statique des requêtes compilées, cela fonctionne très bien. Bien que je n'ai pas encore découvert combien cela fait de différence sur la performance.

1

J'ai passé beaucoup de temps à regarder cela et comment le comportement a été changé dans .NET 4.0. J'ai exposé en détail mes résultats plus en détail dans mon blog ici:

http://www.roushtech.net/2014/01/19/statically-compiled-linq-queries-broken-in-net-4-0/

brut de celui-ci est la suivante: Microsoft a fait un changement pour protéger les gens de faire quelque chose de stupide (réutilisent une requête compilé entre les différentes correspondances), mais semblent avoir brisé un avantage de performance majeur (réutilisation d'une requête compilée entre différents contextes de SAME MAPPING, mais différentes instances de la cartographie). L'utilisation de getters ou d'un composant CompiledQuery membre de votre classe se traduira par une recompilation constante et aucun avantage réel en termes de performances.