Изменение базы с Linq2Sql или Entity Framework
От: Artem Korneev США https://www.linkedin.com/in/artemkorneev/
Дата: 23.03.17 19:37
Оценка:
Есть группа сервисов, работающих с одной и той же базой. Доступ к базе идёт через Linq2Sql и через Entity Framework (разные сервисы, написанные в разное время и разными командами). Со всем этим зоопарком всплывает одна общая проблема — при любом изменении схемы базы данных все эти фреймворки отваливаются.
Я сейчас хочу привести всё это в порядок, унифицировать доступ к базе и, среди прочего, мне нужно предложить какое-то нормальное решение для изменений схемы данных. "Нормальным" в моём понимании будет решение, которое позволит изменять структуру таблиц так, чтоб сервисы, работающие с этими таблицами, не отваливались.
Со стороны самой базы данных всё более-менее понятно — если мы удаляем столбец, то естественно всё развалится. Поэтому удалять столбцы мы будем только после того как столбец удалён из всех linq2sql / EF маппингов. Тут другое. Как сделать чтобы при добавлении столбцов оно не вываливалось с эксепшном о несовпадении схемы?

У меня есть кое-какие мысли о перенаправлении запросов чтения на View вместо самих таблиц, но тогда придётся поддерживать какую-то версионность этих view.. Да и вопрос со вставкой данных остаётся. Другой мысль — обернуть всё в хранимые процедуры, но тогда нужна будет версионность этих процедур..

Мне думается, что этой задачей люди занимались ещё много лет назад и наверняка есть какие-то готовые решения и рекоммендации для Entity Framework или Linq2Sql чтобы избегать таких эксепшнов.
Подскажите, куда стоит копнуть?..
С уважением, Artem Korneev.
Re: Изменение базы с Linq2Sql или Entity Framework
От: TK Лес кывт.рф
Дата: 23.03.17 19:43
Оценка: +4
Здравствуйте, Artem Korneev, Вы писали:

AK>Со стороны самой базы данных всё более-менее понятно — если мы удаляем столбец, то естественно всё развалится. Поэтому удалять столбцы мы будем только после того как столбец удалён из всех linq2sql / EF маппингов. Тут другое. Как сделать чтобы при добавлении столбцов оно не вываливалось с эксепшном о несовпадении схемы?


Просто, при добавлении столбца задавайте ему default значение. У EF никаких проблем с новыми колонками нет.

AK>Мне думается, что этой задачей люди занимались ещё много лет назад и наверняка есть какие-то готовые решения и рекоммендации для Entity Framework или Linq2Sql чтобы избегать таких эксепшнов.


Просто явно перечисляте нужные столбцы без всяких * — уже много лет люди добавляют новые колонки в существующие базы и ничего не отваливается.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[2]: Изменение базы с Linq2Sql или Entity Framework
От: Artem Korneev США https://www.linkedin.com/in/artemkorneev/
Дата: 23.03.17 19:54
Оценка:
Здравствуйте, TK, Вы писали:

TK>Просто, при добавлении столбца задавайте ему default значение. У EF никаких проблем с новыми колонками нет.


Я только начал заниматься проблемой, примеров пока привести не могу. Но вот сегодня "Code First" EF отвалился на SELECT запросе с вот таким сообщением:

"ExceptionMessage": "The model backing the 'TenantAdminDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).",


Не знаю, специфично ли это для Code First или нет, но проблема явно есть. Я бегло просмотрел список изменений за последнюю неделю и пока не вижу ни одного удаления колонок. Только добавление новых таблиц (даже не колонок).

AK>>Мне думается, что этой задачей люди занимались ещё много лет назад и наверняка есть какие-то готовые решения и рекоммендации для Entity Framework или Linq2Sql чтобы избегать таких эксепшнов.

TK>Просто явно перечисляте нужные столбцы без всяких * — уже много лет люди добавляют новые колонки в существующие базы и ничего не отваливается.

Ну столбцы перечисляют, когда запросы вручную пишут. Я же хочу использовать маппинги из Linq2Sql/EF, т.е. читать сразу объекты. Даже если оно там внутри отправляет *, то падать-то, в теории, не должно — старые столбцы никуда не делись, просто новые появились. А на практике — падает. Причём, как Linq2Sql, так и EF (Code First).
С уважением, Artem Korneev.
Re[3]: Изменение базы с Linq2Sql или Entity Framework
От: TK Лес кывт.рф
Дата: 23.03.17 20:24
Оценка:
Здравствуйте, Artem Korneev, Вы писали:

AK>Я только начал заниматься проблемой, примеров пока привести не могу. Но вот сегодня "Code First" EF отвалился на SELECT запросе с вот таким сообщением:


AK>

"ExceptionMessage": "The model backing the 'TenantAdminDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).",


AK>Не знаю, специфично ли это для Code First или нет, но проблема явно есть. Я бегло просмотрел список изменений за последнюю неделю и пока не вижу ни одного удаления колонок. Только добавление новых таблиц (даже не колонок).


Естественно специфично. Просто отключите любые миграции — добавляйте маппинги руками.

AK>Ну столбцы перечисляют, когда запросы вручную пишут. Я же хочу использовать маппинги из Linq2Sql/EF, т.е. читать сразу объекты. Даже если оно там внутри отправляет *, то падать-то, в теории, не должно — старые столбцы никуда не делись, просто новые появились. А на практике — падает. Причём, как Linq2Sql, так и EF (Code First).


CodeFirst в данном случае значит то, что значит. Любые изменения надо вносить в код и только потом они попадают в бд
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[4]: Изменение базы с Linq2Sql или Entity Framework
От: Artem Korneev США https://www.linkedin.com/in/artemkorneev/
Дата: 23.03.17 21:31
Оценка:
Здравствуйте, TK, Вы писали:

TK>CodeFirst в данном случае значит то, что значит. Любые изменения надо вносить в код и только потом они попадают в бд


Дык оно так и было. Изменения внесли через код. Перезапустили один сервис — все остальные сервисы отвалились.
Для варианта CodeFirst есть какие-нибудь способы, не требующие точного совпадения схемы в коде и схемы в базе?
С уважением, Artem Korneev.
Re: Изменение базы с Linq2Sql или Entity Framework
От: Kolesiki  
Дата: 24.03.17 13:32
Оценка:
Здравствуйте, Artem Korneev, Вы писали:

AK> Со всем этим зоопарком всплывает одна общая проблема — при любом изменении схемы базы данных все эти фреймворки отваливаются.


Ну это как бы нормально — ведь это два разных мира — C# и SQL. Обновил базу — перегенерил классы. Возможно, есть тулзы наоборот — по классам модифицировать базу. Но это уже сложнее, ибо система типов SQL более бестолкова и разрозненна. Да и неизвестно, куда мэпить String — в varchar, Nvarchar, NText, с какими лимитами, коллэйшенами и т.п.

AK>Подскажите, куда стоит копнуть?..


Да тут некуда копать — кругом ручная работа. Проще всего — в каком-нть билд-скрипте генерить классы по базе и сравнивать с эталонными.
Re[5]: Изменение базы с Linq2Sql или Entity Framework
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 24.03.17 15:00
Оценка:
Здравствуйте, Artem Korneev, Вы писали:

AK>Здравствуйте, TK, Вы писали:


TK>>CodeFirst в данном случае значит то, что значит. Любые изменения надо вносить в код и только потом они попадают в бд


AK>Дык оно так и было. Изменения внесли через код. Перезапустили один сервис — все остальные сервисы отвалились.

AK>Для варианта CodeFirst есть какие-нибудь способы, не требующие точного совпадения схемы в коде и схемы в базе?

https://metanit.com/sharp/entityframework/2.3.php
https://msdn.microsoft.com/ru-ru/library/gg679461(v=vs.113).aspx

 Database.SetInitializer<userstoredbContext>(null);
Инициализатор или значение NULL используются для отключения инициализации для данного типа контекста.


Ну и проверить на сооьветствие схем можно
http://stackoverflow.com/questions/13089448/how-to-check-if-database-schema-matches-entity-framework-schema
bool isCompatible = context.Database.CompatibleWithModel(true);
и солнце б утром не вставало, когда бы не было меня
Отредактировано 24.03.2017 15:08 Serginio1 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.