Entity Framework и плагинная система -- как совместить?
От: Shmj Ниоткуда  
Дата: 04.07.17 10:53
Оценка:
Прога, которая состоит из набора плагинов.

Есть база данных. Каждый плагин имеет право создавать таблицы и чего-нибудь там хранить.

Можно ли подобное сделать с Entity Framework CodeFirst и где посмотреть пример?

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

А вот передавать контекст между плагинами уже не получится, ведь у нас много разных наследников DbContext.

Как лучше сделать?
Re: Entity Framework и плагинная система -- как совместить?
От: Михаил Романов Удмуртия https://mihailromanov.wordpress.com/
Дата: 04.07.17 11:34
Оценка: 4 (1)
Здравствуйте, Shmj, Вы писали:

S>Как лучше сделать?

Ну я бы, скорее всего, делал как-то так (ранее сам не делал, просто навскидку предлагаю):
Re: Entity Framework и плагинная система -- как совместить?
От: itslave СССР  
Дата: 04.07.17 11:57
Оценка: 2 (1)
Здравствуйте, Shmj, Вы писали:

S>Попробовал сделать базовый DbContext, плагин наследует от него и добавляет свои таблицы (нужно отключить проверку схемы, чтобы это работало). Так каждый плагин может создавать свое подключение и использовать DbContext с новыми таблицами (которые есть только у него).

Я бы не заморачивался с наследованием. Вот тебе база — пиши туда все что хочешь и как хочешь. Возможно бы делал отдельную базу — для секурности.

S>Как лучше сделать?

А вот это уже разлуливал бы кастомным репозиторием типа

IRepository<TItem>
{
     IQueryable Get<T>();
     void Insert/Update/Delete<T>();
}

Скорей всего пришлось бы шаманить в динамике с созданием нужного дб контекста, но это делается один раз в ядре.
Re[2]: Entity Framework и плагинная система -- как совместить?
От: Shmj Ниоткуда  
Дата: 04.07.17 14:58
Оценка:
Здравствуйте, Михаил Романов, Вы писали:

МР>Ну я бы, скорее всего, делал как-то так (ранее сам не делал, просто навскидку предлагаю):

МР>
Это будет работать при одном условии: после подключения нового плагина, базу данных нужно пересоздать заново.

Как бы сделать чтобы происходило обновление схемы?
Re: Entity Framework и плагинная система -- как совместить?
От: liiw  
Дата: 04.07.17 17:15
Оценка: 2 (1)
Здравствуйте, Shmj, Вы писали:

S>Есть база данных. Каждый плагин имеет право создавать таблицы и чего-нибудь там хранить.


Я бы сделал сильно проще.
Не надо никаких контекстов передавать и наследовать. Передавайте строку соединения. Всё. Теперь каждый плагин это как просто самостоятельная программа, которая не зависит от других (в контексте обсуждения БД). И нет проблем.
Отредактировано 04.07.2017 17:16 liiw . Предыдущая версия .
Re[2]: Entity Framework и плагинная система -- как совместить?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 04.07.17 22:47
Оценка: +1
Здравствуйте, liiw, Вы писали:

L>Я бы сделал сильно проще.

L>Не надо никаких контекстов передавать и наследовать. Передавайте строку соединения. Всё. Теперь каждый плагин это как просто самостоятельная программа, которая не зависит от других (в контексте обсуждения БД). И нет проблем.

Вот только если нескольким плагинам понадобится отработать в одной транзакции ..
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[3]: Entity Framework и плагинная система -- как совместить?
От: Михаил Романов Удмуртия https://mihailromanov.wordpress.com/
Дата: 05.07.17 05:50
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Это будет работать при одном условии: после подключения нового плагина, базу данных нужно пересоздать заново.

S>Как бы сделать чтобы происходило обновление схемы?
Ну надо полагать, что потребуется некий механизм миграции.
Стандартная миграция, которую предлагает EF, тут не подойдет, но на базе неё можно нечто эдакое попытаться сделать.

На сколько я помню, стандартный механизм строится на использовании класса DbMigration
Т.е. если бы у вас была штатная ситуация обновления с одной версии базы на другую, у вас получилось бы что-то типа:
public partial class Version_2 : DbMigration
{
    public override void Up()
    {
        AddColumn("dbo.Products""Price", 
    c => c.Decimal(nullable: false, precision: 18, scale: 2));
    }
    
    public override void Down()
    {
        DropColumn("dbo.Products""Price");
    }
}


// И потом вы его примерно так используете:
Database.SetInitializer(new 
    MigrateDatabaseToLatestVersion<SampleDB, Configuration>());
using (var db = new SampleDB())
{
    db.Database.Initialize(false);
}


Проблема в том, что у вас не одна миграция, а композиция миграций (для каждого плагина своя).

Однако, если посмотреть на устройство класса DbMigration, то мы увидим, что по сути там происходит формирование списка из операций изменения базы.

Поэтому, чтобы сильно не ломать схему, можно попробовать сделать так:

Скорее всего, помимо класса миграции придется что-то еще сделать с DbMigrationsConfiguration (т.к. вы собираете конфигурацию "на лету" у вас должен формироваться некий суррогатный номер версии базы).
Re[3]: Entity Framework и плагинная система -- как совместить?
От: swimmers  
Дата: 05.07.17 15:28
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


L>>Я бы сделал сильно проще.

L>>Не надо никаких контекстов передавать и наследовать. Передавайте строку соединения. Всё. Теперь каждый плагин это как просто самостоятельная программа, которая не зависит от других (в контексте обсуждения БД). И нет проблем.

AVK>Вот только если нескольким плагинам понадобится отработать в одной транзакции ..


TransactionScope, или как там его зовут?
Re[4]: Entity Framework и плагинная система -- как совместить?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 05.07.17 17:12
Оценка:
Здравствуйте, swimmers, Вы писали:

S>TransactionScope, или как там его зовут?


С разными коннекшенами? Хочешь DTC замутить с одной БД?
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.