2009-10-02 7 views
1

Je dispose d'un processus de longue durée qui s'intègre à une collection d'entités entrantes pour déterminer si l'entité entrante est différente de l'entité dans le stockage persistant. Quand j'ai écrit ceci pour la première fois, j'ai récupéré chaque entité de la base de données qui correspondait à l'entité que je comparais, j'ai aussi eu quelques inclusions pour extraire des entités référencées que j'avais aussi besoin de comparer. C'était incroyablement lent car chaque comparaison impliquait une requête de base de données et ensuite Entity Framework 'réparer'. J'utilise maintenant une requête pour extraire toutes les entités dont j'ai besoin pour mes comparaisons avant de commencer le processus. Cela me permet de prendre la vitesse à l'avant afin que je puisse accélérer considérablement mon processus. Cependant, la requête initiale nécessite encore au moins une minute ou deux pour s'exécuter.Quel est le meilleur moyen de conserver un graphe d'objet Entity Framework en mémoire?

Dictionary<long, SomeEntity> someEntities = new SomeEntitiesInclude().ApplyTo(context.SomeEntities) 
                 .Where(se => se.SomeRelatedEntity.ID == relatedEntityID) 
                 .Where(se => se.SCDCurrent == true) 
                 .OrderBy<SomeEntity, long>(se => se.SomeRelatedEntity.ID) 
                 .ToDictionary<SomeEntity, long>(se => se.SomeRelatedEntity.ID); 

La requête sql réelle produite à partir de cela ne prend que quelques secondes pour exécuter je pense que la plupart du temps est consacré à faire « réparer » si le contexte peut suivre les changements.

L'objet SomeEntitiesInclude me permet d'utiliser des déclarations comprennent fortement typé et est une sous-classe de la classe IncludeStratergy développée par Alex James: http://blogs.msdn.com/alexj/archive/2009/07/25/tip-28-how-to-implement-include-strategies.aspx

Est-ce que quelqu'un a des conseils pour accélérer l'exécution de ce?

Toutes mes excuses pour la longue question.

James

Répondre

0

Il y a plusieurs choses qui pourraient ralentir cette baisse. Fixez celui d'entre eux. Il est facile de tester si la réparation est le problème, en projetant sur un type non-entité. Cela supprime complètement l'équation de l'équation. Si cela résout le problème, alors il a probablement été décidé de ralentir les choses, et nous pouvons impliquer la solution à partir de là. D'autre part, il pourrait ne pas résoudre le problème, car il y a d'autres choses qui pourraient ralentir l'exécution de la requête. Par contre, cela peut ne pas résoudre le problème. La première chose que je voudrais regarder est la compilation de la requête d'une expression LINQ en SQL. Vous pouvez séparer cette étape en utilisant le type CompiledQuery. Si la production de CompiledQuery prend beaucoup de temps, mais que l'exécution de la méthode résultante prend très peu de temps, vous avez trouvé la source du problème de performance.

Avant de faire tout cela, je ferais probablement en sorte que votre requête ne soit pas inutilement compliquée. Sans savoir ce que vous faites, précisément, je ne peux pas dire si vous avez réellement besoin de tous les champs que vous retournez. Mais si vous n'avez besoin que de quelques champs de quelques types, vous feriez bien de projeter sur un type non-entité, plutôt que de renvoyer des entités entièrement matérialisées.

+0

Merci Craig, réponse très utile, cela me donne au moins un point de départ pour enquêter. – James

Questions connexes