Entity Framework 6 беше и все още остава „работен кон“ за достъп до данни в корпоративни приложения, базирани на .NET, главно поради своята стабилност, ниска бариера за навлизане и широка известност. Затова се надявам, че тази статия все още ще бъде полезна.

„Първа база данни без EDMX“

Наистина не искам да навлизам в стария дебат за Code First срещу Database First. Вместо това, по-добре да напиша няколко думи за това как да улесня живота ви, ако предпочитате Database First. Много разработчици, които предпочитат този подход, се оплакват от неудобства при работа с досадния EDMX файл. Този файл може да превърне екипното развитие в истински ад: значително забавя сливането на паралелни промени поради постоянното „смесване“ на вътрешната му структура. Що се отнася до моделите с няколкостотин екземпляра (типичен наследен монолит), можете да се сблъскате със силно забавяне на скоростта на всяко действие, когато работите със стандартния EDMX дизайнер.

Решението изглежда съвсем очевидно - трябва да се откажете от EDMS и да предпочетете алтернативно средство за генериране на POCO и съхранение на метаданни. Е, изглежда като проста задача и EF има функцията за генериране на код първо от базата данни, която е жизнеспособна във Visual Studio (със сигурност във VS2015). Но в реалния живот прехвърлянето на промени в базата данни върху получения модел е много неудобно с този инструмент. Освен това всеки, който работи с EF от дълго време, си спомня разширението Entity Framework Power Tools, което решава подобни проблеми, но за съжаление този проект изглежда почти мъртъв (не можете да го инсталирате на VS2015 без хакване) и част от разработчиците му сега работят в екипа на EF.

Когато всичко изглеждаше толкова зле, намерих EntityFramework Reverse POCO Generator. Това е шаблон T4 за генериране на POCO на базата на съществуващата база данни с голям брой настройки и „код с отворен код“. Той поддържа всички основни функции на EDMX и включва набор от допълнителни съвети: генериране на FakeDbContext/FakeDbSet за тестване на модули, покритие на атрибути за модели (напр. DataContract/DataMember) и други. Освен това T4 осигурява пълен контрол върху генерирането на код. За да обобщим: работи последователно, екипът се радва и миграцията на съществуващи проекти върви гладко.

„Работа с отделни графики“

Обикновено прикачването на нов обект или обект, който преди това е бил генериран в друг контекст, е проста задача. Проблемите започват, когато става въпрос за графики, тоест обекти с връзки: EF „извън кутията“ не проследява промените в съдържанието на навигационните свойства на обект, прикрепен отново към контекста. За да се проследят промените, съответният запис трябва да съществува (обект със служебна информация, включително информация за състоянието на обекта — добавен, променен, изтрит и т.н.) за всеки обектен обект по време на жизнения цикъл на контекста. Можете да попълните записи за добавяне на графика по следните 2 начина:

  1. Можете да съхранявате състоянието в обектите и да проследявате промените сами. По този начин нашата отделена графика ще съдържа цялата информация, необходима за свързване.
  2. Не можете да направите нищо предварително и когато прикачите графика към контекста, трябва да изтеглите изходната графика от DB и да зададете състоянията на обекта въз основа на сравнението на две графики.

Пример за решение №1 може да бъде намерен в курса „Pluralsight” от Джули Лерман, известен експерт по EF. Ще трябва да предприемете голям брой стъпки за неговото прилагане. Всички обекти трябва да имплементират интерфейса IsteObject:

публичен интерфейс IStateObject
{
ObjectState State { get; комплект;
}

По един или друг начин трябва да гарантираме уместността на стойностите на състоянието след ръчно добавяне на всеки графичен обект към контекста

context.Foos.Attach(foo);

за да преминете през всички записи, като редактирате техните състояния:

IStateObject entity = entry.Entity;
entry.State = ConvertState(entity.State);

В този случай няма да имаме нужда от допълнителни извиквания на DB, но решението се оказва твърде голямо, крехко и потенциално неработещо за отношенията много към много. Освен това, той обработва модели (между другото, изискването за внедряване на интерфейс може да бъде разширено с модификация на T4 шаблоните от предишния раздел на тази статия).

Нека разгледаме накратко решение №2:

context.UpdateGraph(root, map =› map.OwnedCollection(r =› r.Childs));

Това извикване ще добави основния обект към контекста. При това ще актуализира свойството за навигация с колекцията от обекти на Childs посредством единичен SELECT към DB. Вече е възможно благодарение на библиотеката GraphDiff. Авторът на библиотеката е направил цялата мръсна работа и е поправил основни грешки.

Продължете да четете статията тук https://goo.gl/eaEsP8, където разкрихме и следните въпроси:

  • „SQL модификация“.
  • „Кеширане на данни извън границите на жизнения цикъл на DbContext“.
  • Повторен опит при грешки от SQL Server
  • „Замяна на DbContext, изолиране от истинската DB“.
  • „Бързо вмъкване“.

Благодаря за четенето!