36 votes

L’initialisation d’Entity Framework est lente - que puis-je faire pour l’amorcer plus rapidement?

Mon EF 4.3.1 modèle a 200 et quelques tables. Démarrage Initial est horrible, plusieurs minutes. Un DotTrace-capturé profil implique une certaine terrible algorithme/évolutivité des choix profondément dans le cadre, comme en témoignent les millions d'appels à un certain nombre de méthodes là-bas et les 36 millions de IEnumerable.Contient() appelle. Voici un extrait de code, tout est déclenché par la première requête effectuée sur la base de données (futures requêtes ne faites pas cela et sont très bien).

enter image description here

Que puis-je faire pour mon modèle pour le rendre moins douloureux? Puis-je précompiler ce en quelque sorte? Mieux, l'équipe EF veuillez répondre à ces questions ou open source le cadre donc, je peux? Ou au moins de corriger l'orthographe de l' Warapper? :)

EDIT: Un EF appel qui déclenche ce est fondamentalement var db = new MyDbContext(); db.Personnel.Where(a => a.Login == login).SingleOrDefault();. Aussi un EF Migrations de Semences() AddOrUpdate génère en effet de la même pile. Le plus complet que la trace de la pile, ce qui peut donner un peu plus de contexte, c'est ici: Fuller Trace de la Pile

EDIT: Quelques liens pertinents:

EDIT2: Maintenant que l'on vient de open source le code, il semble que cette ligne:

//Filter the 1:1 foreign key associations to the ones relating the sets used in these cell wrappers.
oneToOneForeignKeyAssociationsForThisWrapper =
    oneToOneForeignKeyAssociationsForThisWrapper.Where(
        it => (it.AssociationEndMembers.All(endMember => entityTypes.Contains(endMember.GetEntityType()))));

est celui qui a besoin de quelques travaux. C'est à l'aide d'un O(n^2) algorithme lorsqu'il n'a sans doute pas, mais je n'ai pas regardé de plus près encore.

EDIT3: Heureusement, il ressemble à un travail en EF6 est la fixation de ce code: http://entityframework.codeplex.com/discussions/396130

23voto

Pawel Points 12600

En pré EF6 vue de la génération est connu pour être lent pour les plus gros modèles. Pour l'instant, la solution est d'utiliser préfabriqués points de vue. De cette façon, vous susciter des points de vue au moment de la conception et évitent de ce travail au moment de l'exécution. Pour ce faire télécharger EF puissance des outils et sélectionnez "Optimiser le Modèle de Données d'Entité". Il va ajouter un fichier C# pour votre projet, qui contient des points de vue. L'inconvénient est que vous devrez le faire à chaque fois vos changements de modèle. Remarque: pour générer des vues avec l'outil, il faudra environ la même quantité de temps qu'il faut pour susciter des points de vue au moment de l'exécution (donc parfois vous avez besoin d'être patient). Voici un post sur EF Puissance des Outils qui pourraient être utiles: http://blogs.msdn.com/b/adonet/archive/2011/05/18/ef-power-tools-ctp1-released.aspx

Modifier

Récemment, j'ai créé une autre solution qui est beaucoup plus pratique à utiliser (à noter qu'il ne fonctionne que sur EF6) - http://blog.3d-logic.com/2013/12/14/using-pre-generated-views-without-having-to-pre-generate-views-ef6/

12voto

Pawel Points 12600

Voici une autre façon de le faire. Il nécessite un peu de travail manuel, mais peut en fait être plus adaptés à votre scénario dans lequel vous souhaitez utiliser MsBuild. Au lieu de créer des vues avec des Outils électriques (je suis désolé d'entendre qu'ils ne fonctionnent pas pour vous), vous pouvez créer manuellement - voici les étapes:

  • Vous devez d'abord obtenir des artefacts pour votre contexte. Vous avez besoin de tous les csdl, lsed et msl fichiers. Vous pouvez utiliser EdmxWriter pour obtenir ces. Notez que EdmxWriter renvoie un fichier edmx qui combine tous les trois fichiers si vous avez besoin de les diviser. Voici le code de cette étape (à noter que les espaces de noms sont spécifiques à EF4, si vous envisagez d'utiliser EF5 et .NET Framework 4.5, vous aurez besoin de les modifier en conséquence ou sélectionner des éléments par nom local et pas le nom complet):

    var ms = new MemoryStream();
    using (var writer = XmlWriter.Create(ms))
    {
        EdmxWriter.WriteEdmx(new Context(), writer);
    }

    ms.Position = 0;

    var xDoc = XDocument.Load(ms);

    var ssdl = xDoc.Descendants("{http://schemas.microsoft.com/ado/2009/02/edm/ssdl}Schema").Single();
    var csdl = xDoc.Descendants("{http://schemas.microsoft.com/ado/2008/09/edm}Schema").Single();
    var msl = xDoc.Descendants("{http://schemas.microsoft.com/ado/2008/09/mapping/cs}Mapping").Single();

    ssdl.Save("Context.ssdl");
    csdl.Save("Context.csdl");
    msl.Save("Context.msl");
  • Lorsque vous avez des artefacts, vous pouvez générer des vues à l'aide de EdmGen outil. Depuis ici, nous le faisons manuellement, vous devez le faire à partir de la VS invite de Commande. Voici la commande que vous utilisez pour générer des vues:
EdmGen /mode:ViewGeneration /incsdl:Context.csdl  /inmsl:Context.msl /inssdl:Context.ssdl /outviews:Context.Views.cs
  • Ajouter le fichier généré à votre projet.

Si vous souhaitez intégrer vue de la génération de votre système de construction, il reste une option intéressante - à l'aide d'un modèle T4. Le modèle permettrait de prendre soin des étapes ci-dessus. Vous pouvez trouver plus de détails sur cette approche ici http://blogs.msdn.com/b/adonet/archive/2008/06/20/how-to-use-a-t4-template-for-view-generation.aspx. Le seul problème est que l'exemple n'est pas pour CodeFirst approche, donc il doit être changé un peu ce qui ne devrait pas être dur.

J'ai effectivement créé des modèles T4 pour le Premier Code. Vous pouvez trouver un lien pour le télécharger dans mon post de blog: http://blog.3d-logic.com/2012/05/28/entity-framework-code-first-and-pre-generated-views/

Les modèles sont maintenant disponibles sur le Code de Visual Studio Gallery. Voici le lien vers le post avec tous les détails: http://blog.3d-logic.com/2012/06/13/entity-framework-codefirst-view-generation-templates-on-visual-studio-code-gallery/

1voto

lukasLansky Points 306

La génération de vues est en fait assez rapide dans la version actuelle d’Entity Framework. (6.1) Une autre solution de mise en cache plus vaste est en préparation: https://entityframework.codeplex.com/workitem/1876 . Vous pouvez attendre que ce correctif soit accepté ou, si vous êtes assez courageux, vous pouvez l'appliquer vous-même.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X