A boot do Entity Framework é SLOW – o que posso fazer para inicializá-lo mais rápido? DoCow
c # desempenho entity framework 4 entity framework 4.3
A boot do Entity Framework é SLOW – o que posso fazer para inicializá-lo mais rápido?
Meu modelo EF 4.3.1 tem 200 tabelas ímpares. Inicialização inicial é horrível, vários minutos. Um perfil capturado por DotTrace implica algumas escolhas terríveis de algoritmo / escalabilidade no âmbito do framework, como evidenciado pelos milhões de chamadas para vários methods lá em baixo e as 36 milhões de chamadas IEnumerable.Contains (). Aqui está um trecho, tudo isso é acionado pela primeira consulta feita no database (consultas futuras não fazem isso e estão bem).
O que posso fazer com o meu modelo para tornar isso menos doloroso? Posso pré-compilar isso de alguma forma? Melhor, a equipe da EF pode resolver esses problemas ou abrir o código-fonte para que eu possa? Ou pelo menos consertar a grafia de Warapper ? 🙂
EDIT: Uma chamada EF específica que aciona isso é basicamente var db = new MyDbContext(); db.Personnel.Where(a => a.Login == login).SingleOrDefault(); var db = new MyDbContext(); db.Personnel.Where(a => a.Login == login).SingleOrDefault(); . Também um AddOrUpdate do EF Migrations Seed () gera efetivamente a mesma pilha. O rastreamento de pilha mais completo, que pode fornecer um pouco mais de contexto, está aqui: Fuller Trace Stack
appSettings vs applicationSettings. appSettings desatualizados?
Por que devo usar a palavra-chave "using" para acessar meu método de class base?
Como obter * internet * IP?
Estreitamento de um valor de macro
EDIT: alguns links relevantes:
MSDN: Considerações sobre desempenho (Entity Framework) (graças a @AakashM)
MSDN: EF Power Tools
SO: Entity Framework 4.1 para grande número de tabelas (715)
EDIT2: Agora que eles apenas abriram o código, parece que esta linha:
//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()))));
é aquele que precisa de algum trabalho. Está usando um algoritmo O (n ^ 2) quando provavelmente não precisa, mas ainda não olhei de perto.
EDIT3: Felizmente, parece que o trabalho no EF6 está corrigindo este código: http://entityframework.codeplex.com/discussions/396130
No pré EF6, a geração de visualizações é conhecida como lenta para modelos maiores. Por enquanto, a solução é usar visualizações pré-geradas. Dessa forma, você gera visualizações em tempo de design e está evitando esse trabalho em tempo de execução. Para isso, faça o download das ferramentas elétricas EF e selecione "Otimizar modelo de dados de entidade". Ele adicionará um arquivo C # ao seu projeto que contém visualizações. O lado negativo é que você precisará fazer isso toda vez que seu modelo for alterado. Nota: para gerar visualizações com a ferramenta, o tempo necessário para gerar visualizações em tempo de execução é o mesmo (por isso, às vezes, você precisa ser paciente). Aqui está um post sobre EF Power Tools que pode ser útil: http://blogs.msdn.com/b/adonet/archive/2011/05/18/ef-power-tools-ctp1-released.aspx
Recentemente eu criei uma solução diferente que é muito mais conveniente de usar (note que só funciona no EF6) – http://blog.3d-logic.com/2013/12/14/using-pre-generated-views-without- tendo-para-pre-generate-views-ef6 /
Aqui está outra maneira de fazer isso. Ele requer um pouco de trabalho manual, mas pode ser mais adequado ao cenário em que você gostaria de usar o MsBuild. Em vez de criar visualizações com o Power Tools (lamento saber que elas não funcionaram para você), você pode criá-las manualmente – aqui estão as etapas:
Primeiro você precisa obter artefatos para o seu contexto. Você precisa de todos os arquivos – csdl, ssdl e msl. Você pode usar o EdmxWriter para obtê-los. Note que o EdmxWriter retorna um arquivo edmx que combina todos os três arquivos, então você precisa dividi-los. Aqui está o código para esta etapa (note que namespaces são específicos do EF4, se você está pensando em usar o EF5 e o .NET Framework 4.5, você precisará alterá-los de acordo ou selecionar elementos apenas pelo nome local e não pelo 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 você tem artefatos, pode gerar visualizações usando a ferramenta EdmGen. Como aqui fazemos isso manualmente, você precisa fazer isso no prompt do VS Command. Aqui está o comando que você usa para gerar visualizações:
EdmGen /mode:ViewGeneration /incsdl:Context.csdl /inmsl:Context.msl /inssdl:Context.ssdl /outviews:Context.Views.cs
Adicione o arquivo gerado ao seu projeto.
Se você deseja integrar a geração de visualizações ao seu sistema de construção, há mais uma opção interessante – usando um modelo T4. O modelo cuidaria dos passos acima. Você pode encontrar mais detalhes sobre essa abordagem aqui http://blogs.msdn.com/b/adonet/archive/2008/06/20/how-to-use-a-t4-template-for-view-generation.aspx . O único problema é que o exemplo não é para a abordagem CodeFirst, então é necessário alterá-lo um pouco, o que não deve ser difícil.
Na verdade, criei modelos T4 para o Code First. Você pode encontrar um link para baixar no meu post: http://blog.3d-logic.com/2012/05/28/entity-framework-code-first-and-pre-generated-views/
Os modelos estão agora disponíveis no Visual Studio Code Gallery. Aqui está o link para o post com todos os detalhes: http://blog.3d-logic.com/2012/06/13/entity-framework-codefirst-view-generation-templates-on-visual-studio-code- galeria/
A geração de visualizações é, na verdade, bastante rápida na versão atual do Entity Framework. (6.1) Há outra solução de armazenamento em cache mais ampla em preparação: https://entityframework.codeplex.com/workitem/1876 . Você pode esperar que este patch seja aceito, ou, se você for corajoso o suficiente, você pode aplicá-lo por si mesmo.