Инициализация платформы Entity – SLOW – что я могу сделать, чтобы быстрее запустить ее?

Моя модель EF 4.3.1 имеет 200 с лишним таблиц. Начальный запуск ужасен, несколько минут. Профиль, захваченный DotTrace, подразумевает некоторые ужасные варианты алгоритма / масштабируемости в глубине структуры, о чем свидетельствуют миллионы вызовов ряда методов и 36 миллионов вызовов IEnumerable.Contains (). Вот fragment, все это вызвано первым запросом, сделанным в базе данных (будущие запросы не делают этого, и все в порядке).

введите описание изображения здесь

Что я могу сделать с моей моделью, чтобы сделать это менее болезненным? Могу ли я предварительно скомпоновать это? Лучше, может ли команда EF решить эти проблемы или открыть исходный код, чтобы я мог? Или, по крайней мере, исправить написание Warapper ? 🙂

EDIT: Один конкретный вызов EF, который вызывает это, в основном var db = new MyDbContext(); db.Personnel.Where(a => a.Login == login).SingleOrDefault(); var db = new MyDbContext(); db.Personnel.Where(a => a.Login == login).SingleOrDefault(); , Также EF Migrations Seed () AddOrUpdate эффективно генерирует один и тот же стек. Более полная трассировка стека, которая может дать немного больше контекста, здесь: Fuller Stack Trace

EDIT: Некоторые релевантные ссылки:

  • MSDN: соображения производительности (платформа Entity Framework) (благодаря @AakashM)
  • MSDN: Электроинструменты EF
  • SO: Entity Framework 4.1 для большого количества таблиц (715)

EDIT2: теперь, когда они просто открывают исходный код, кажется, что эта строка:

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

это тот, который нуждается в некоторой работе. Он использует алгоритм O (n ^ 2), когда это, вероятно, не обязательно, но я еще не пристально смотрел.

EDIT3: К счастью, похоже, что работа в EF6 – это исправление этого кода: http://entityframework.codeplex.com/discussions/396130

В режиме предварительного EF6 генерация, как известно, является медленной для больших моделей. На данный момент решение состоит в использовании прегенерированных представлений. Таким образом вы генерируете представления во время разработки и избегаете этой работы во время выполнения. Для этого загрузите инструменты электропитания EF и выберите «Оптимизировать модель данных сущностей». Он добавит в ваш проект файл C #, содержащий представления. Нижняя сторона – это то, что вам нужно будет делать это каждый раз, когда ваша модель меняется. Примечание: для создания представлений с помощью инструмента потребуется примерно столько же времени, сколько требуется для создания представлений во время выполнения (поэтому иногда вам нужно быть терпеливым). Вот сообщение об инструментах EF Power Tools, которые могут быть полезны: http://blogs.msdn.com/b/adonet/archive/2011/05/18/ef-power-tools-ctp1-released.aspx

редактировать

Недавно я создал другое решение, которое гораздо удобнее использовать (обратите внимание, что он работает только на EF6) – http://blog.3d-logic.com/2013/12/14/using-pre-generated-views-without- имеющие к прегенерация-вид-EF6 /

Вот еще один способ сделать это. Это требует немного ручной работы, но на самом деле может быть более подходящим для вашего сценария, где вы хотели бы использовать MsBuild. Вместо создания представлений с помощью Power Tools (извините, что они не сработали для вас) вы можете создать их вручную – вот шаги:

  • Сначала вам нужно получить артефакты для вашего контекста. Вам нужны все – csdl, ssdl и msl файлы. Вы можете использовать EdmxWriter для их получения. Обратите внимание, что EdmxWriter возвращает файл edmx, который объединяет все три файла, поэтому вам нужно их разделить. Вот код для этого шага (обратите внимание, что пространства имен специфичны для EF4, если вы думаете об использовании EF5 и .NET Framework 4.5, вам необходимо соответствующим образом изменить их или выбрать элементы только по локальному имени, а не по полному имени):
 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"); 
  • Когда у вас есть артефакты, вы можете создавать представления с помощью инструмента EdmGen. Поскольку здесь мы делаем это вручную, вам нужно сделать это из командной строки VS. Вот команда, которую вы используете для создания представлений:
 EdmGen /mode:ViewGeneration /incsdl:Context.csdl /inmsl:Context.msl /inssdl:Context.ssdl /outviews:Context.Views.cs 
  • Добавьте сгенерированный файл в ваш проект.

Если вы хотите интегрировать создание представлений с вашей системой сборки, есть еще один интересный вариант – с использованием шаблона T4. Шаблон позаботится о вышеуказанных шагах. Более подробную информацию об этом подходе вы найдете здесь http://blogs.msdn.com/b/adonet/archive/2008/06/20/how-to-use-a-t4-template-for-view-generation.aspx , Единственная проблема заключается в том, что пример не для подхода CodeFirst, поэтому его нужно немного изменить, что не должно быть трудно.

Я создал T4 шаблоны для Code First. Вы можете найти ссылку для загрузки в моем сообщении в блоге: http://blog.3d-logic.com/2012/05/28/entity-framework-code-first-and-pre-generated-views/

Шаблоны теперь доступны в Visual Studio Code Gallery. Вот ссылка на сообщение со всеми подробностями: http://blog.3d-logic.com/2012/06/13/entity-framework-codefirst-view-generation-templates-on-visual-studio-code- галерея/

В текущей версии Entity Framework представление поколений на самом деле довольно быстро. (6.1) В подготовке есть еще одно, более широкое решение для кэширования: https://entityframework.codeplex.com/workitem/1876 . Вы можете дождаться, когда этот патч будет принят, или, если вы достаточно храбры, вы можете применить его для себя.

  • C ++: Поймать деление на нулевую ошибку
  • Использование инструкций процессора AVX: низкая производительность без «/ arch: AVX»
  • В java, эффективнее ли использовать байты или короткие вместо int и float вместо double?
  • C ++ cout печать медленно
  • Является ли оператор LINQ быстрее, чем цикл foreach?
  • Есть ли преимущество использования карты над unordered_map в случае тривиальных ключей?
  • SSD и нетбук - замораживание во время ввода-вывода
  • Подтверждение того, что Windows 7 использует оптимизацию SSD
  • Google Chrome работает медленнее до localhost
  • Самый быстрый способ чтения относительно огромных байтовых файлов в Java
  • System.currentTimeMillis () против новой Date () vs. Calendar.getInstance (). GetTime ()
  • Давайте будем гением компьютера.