L’inizializzazione di Entity Framework è SLOW – cosa posso fare per eseguire il bootstrap più velocemente?

Il mio modello EF 4.3.1 ha 200 tavoli dispari. L’avvio iniziale è orribile, alcuni minuti. Un profilo acquisito da DotTrace implica alcune terribili opzioni di algoritmo / scalabilità nel framework, come evidenziato dai milioni di chiamate a un numero di metodi laggiù e dalle 36 milioni di chiamate IEnumerable.Contains (). Ecco uno snippet, questo è tutto triggersto dalla prima query eseguita sul database (le query future non lo fanno e vanno bene).

inserisci la descrizione dell'immagine qui

Cosa posso fare al mio modello per renderlo meno doloroso? Posso precompilare questo in qualche modo? Meglio, il team EF può rivolgere questi problemi o open source al framework, così posso? O almeno correggere l’ortografia di Warapper ? 🙂

EDIT: una chiamata EF specifica che triggers questo è fondamentalmente var db = new MyDbContext(); db.Personnel.Where(a => a.Login == login).SingleOrDefault(); var db = new MyDbContext(); db.Personnel.Where(a => a.Login == login).SingleOrDefault(); . Anche un seme di migrazione EF () AddOrUpdate genera in modo efficace lo stesso stack. La traccia dello stack più completo, che può dare un po ‘più di contesto, è qui: Fuller Stack Trace

EDIT: alcuni link rilevanti:

  • MSDN: Considerazioni sulle prestazioni (Entity Framework) (grazie a @AakashM)
  • MSDN: EF Power Tools
  • SO: Entity Framework 4.1 per un numero elevato di tabelle (715)

EDIT2: Ora che hanno appena aperto il codice, sembra che questa linea:

 //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())))); 

è quello che ha bisogno di un po ‘di lavoro. Sta usando un algoritmo O (n ^ 2) quando probabilmente non è necessario, ma non ho ancora guardato da vicino.

EDIT3: Fortunatamente, sembra che il lavoro in EF6 risolva questo codice: http://entityframework.codeplex.com/discussions/396130

Nella generazione pre EF6 è noto che la generazione è lenta per i modelli più grandi. Per ora la soluzione è usare viste pregenerate. In questo modo si generano visualizzazioni in fase di progettazione e si evita questo lavoro in fase di runtime. Per fare ciò, scaricare gli strumenti di alimentazione EF e selezionare “Ottimizza modello dati entity framework”. Aggiungerà un file C # al progetto che contiene viste. Il lato negativo è che dovrai farlo ogni volta che il tuo modello cambia. Nota: per generare viste con lo strumento ci vorrà circa lo stesso tempo impiegato per generare viste in fase di esecuzione (quindi a volte è necessario essere pazienti). Ecco un post su EF Power Tools che potrebbe essere utile: http://blogs.msdn.com/b/adonet/archive/2011/05/18/ef-power-tools-ctp1-released.aspx

modificare

Recentemente ho creato una soluzione diversa che è molto più comoda da usare (si noti che funziona solo su EF6) – http://blog.3d-logic.com/2013/12/14/using-pre-generated-views-without- dover-a-pre-generate-vista-EF6 /

Ecco un altro modo per farlo. Richiede un po ‘di lavoro manuale, ma può essere più adatto allo scenario in cui si desidera utilizzare MsBuild. Invece di creare visualizzazioni con Power Tools (mi dispiace sapere che non hanno funzionato per te) puoi crearle manualmente: ecco i passaggi:

  • Per prima cosa devi ottenere artefatti per il tuo contesto. Hai bisogno di tutti i file – csdl, ssdl e msl. È ansible utilizzare EdmxWriter per ottenere questi. Si noti che EdmxWriter restituisce un file edmx che combina tutti e tre i file, quindi è necessario dividerli. Ecco il codice per questo passaggio (si noti che gli spazi dei nomi sono specifici per EF4, se si sta pensando di utilizzare EF5 e .NET Framework 4.5 sarà necessario modificarli di conseguenza o selezionare gli elementi solo in base al nome locale e non al nome completo):
 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"); 
  • Quando hai artefatti puoi generare viste usando lo strumento EdmGen. Poiché qui lo facciamo manualmente, devi farlo dal prompt dei comandi VS. Ecco il comando che usi per generare viste:
 EdmGen /mode:ViewGeneration /incsdl:Context.csdl /inmsl:Context.msl /inssdl:Context.ssdl /outviews:Context.Views.cs 
  • Aggiungi il file generato al tuo progetto.

Se vuoi integrare la generazione di viste con il tuo sistema di costruzione, c’è un’altra opzione interessante: usare un modello T4. Il modello si prenderà cura dei passaggi precedenti. Puoi trovare maggiori dettagli su questo approccio qui http://blogs.msdn.com/b/adonet/archive/2008/06/20/how-to-use-a-t4-template-for-view-generation.aspx . L’unico problema è che l’esempio non è per l’approccio CodeFirst, quindi è necessario modificarlo un po ‘, cosa che non dovrebbe essere difficile.

Realmente ho creato i modelli T4 per Code First. Puoi trovare un link da scaricare nel post del mio blog: http://blog.3d-logic.com/2012/05/28/entity-framework-code-first-and-pre-generated-views/

I modelli sono ora disponibili su Visual Studio Code Gallery. Ecco il link al post con tutti i dettagli: http://blog.3d-logic.com/2012/06/13/entity-framework-codefirst-view-generation-templates-on-visual-studio-code- galleria/

La generazione della vista è infatti abbastanza veloce nella versione corrente di Entity Framework. (6.1) È in preparazione un’altra soluzione di caching più ampia: https://entityframework.codeplex.com/workitem/1876 . Puoi aspettare che questa patch sia accettata, oppure, se sei abbastanza coraggioso, puoi applicarla da solo.