...

среда, 6 ноября 2013 г.

[Из песочницы] Попытка перехода с Entity Framework 5 на 6 или DataBase-First = Code-First + браузер диаграммы

Хочу поделиться граблями перехода с EFW 5 на 6 в случае DataBase-First.

Тесно работаю с Entity Framework с пелёнок. Пересел на него с Linq2SQL.

Особых проблем с переходами между версиями не встречал. И в целом — каждый переход оправдывал ожидания.

Но сегодня я был слегка разочарован.



На старте у меня есть 6 штук DataBase-First репозиториев, раскиданных по солюшену VS 2012 на .NET 4.5. И я их попытался перевести на EFW 6.


Итак, что нужно делать и в каком порядке.


1. Зайти в менеджер NuGet (Manage NuGet Packages), открыть вкладку Updates и установить Entity Framework 6 (6.0.1)

Эта процедура удалит ссылки на старые сборки и добавит две новые сборки в проект (EntityFramework.dll, EntityFramework.SqlServer.dll)

Это нужно сделать для каждого проекта, где есть EFW. Если всё это в итоге запускается где-то в другом приложении — то там необходимо внести аналогичные изменения в app.config (web.config)


2. У вас в проекте появится масса ошибок компиляции. Но не спешите их исправлять. Сначала мы заменим генератор сущностей и, тем самым, автоматически исправим часть ошибок. Если в проекте уже использовались генераторы — удаляем (ищем и удаляем *.tt)

Идем в просмотр диаграммы, жмем правую педаль и выбираем «Add Code Generation Item» и выбираем «EF 6.x DBContextGenerator».

Если у вас установлена VS 2012 (а не 2013), то предварительно нужно установить Entity Framework Tools 6


3. Теперь исправляем ошибки компиляции.

Как правило, ошибки связаны с тем, что изменились namespace.

Шаблон изменений в большинстве случаев такой: после System.Data добавляется .Entity.Core.


Всё, проект готов к запуску.


А теперь о граблях.


1. Пропало (перенесено) куча методов, которые не исправить в коде автоматически.

Например:

Context.DeleteObject() больше нет, теперь иди в нужный DbSet и вызывай Remove() там.



context.Delete(user); //было
context.Users.Remove(user); //стало


Context.AddTo*** тоже теперь нет, иди в нужный DbSet и вызывай Add() там.



context.AddToUsers(user); //было
context.Users.Add(user); //стало


Метода DbSet.AddObject тоже не стало, но тут можно решить автозаменой [AddObject] => [Add]

Особо продвинутые могут написать Extension.


2. Изменились внутренние типы.

Если раньше context.Connection был типа EntityConnection

То теперь там вдруг оказался SqlConnection.

Что поломало часть моего кода (смысл кода был — в «узких» местах узнать строку соединения и на ADO.Net сделать нужные вещи)


3. Вообще пропали события у контекста.

Т.е. теперь context.SavingChanges события просто нет.


4. Классы, которые генерируются теперь не обладают былой функциональностью. Я бы сказал, что они теперь от структур вообще не отличаются.

Они даже не наследуются от EntityObject.


5. Было два репозитория, основанных на разных БД. В них присутствовали таблицы с одинаковыми именами. В итоге в репозиториях были классы с одинаковыми именами, но разными пространствами имен. На Entity Framework 5 это не создавало проблем. А вот на 6-ке код скомпилировался, но в runtime я поймал exception, что-то про невозможность разрешения имени (в сообщении фигурировали эти самые классы из разных пространств имен)


Пункты 3 и 4 наводят меня на мысль, что DataBase-First подход был слит. Остался лишь Code-First + ширма в виде браузера диаграммы классов.


Ну и фаталити — после перехода на 6.0.1 мой код стал работать медленнее.

Возможно, дело в том, что стали генерироваться другие, более оптимальные запросы и они пошли мимо индексов, созданных для EFW 5.

Но разбираться в причинах я уже не стал. Просто отложил переход на более свободное время.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends:



Комментариев нет:

Отправить комментарий