Есть база данных. Каждый плагин имеет право создавать таблицы и чего-нибудь там хранить.
Можно ли подобное сделать с Entity Framework CodeFirst и где посмотреть пример?
Попробовал сделать базовый DbContext, плагин наследует от него и добавляет свои таблицы (нужно отключить проверку схемы, чтобы это работало). Так каждый плагин может создавать свое подключение и использовать DbContext с новыми таблицами (которые есть только у него).
А вот передавать контекст между плагинами уже не получится, ведь у нас много разных наследников DbContext.
Как лучше сделать?
Re: Entity Framework и плагинная система -- как совместить?
Здравствуйте, Shmj, Вы писали:
S>Как лучше сделать?
Ну я бы, скорее всего, делал как-то так (ранее сам не делал, просто навскидку предлагаю):
Для каждого плагина выделил бы какой-то метод, который будет отвечать за настройку модели. По сигнатуре можно сделать его по образу и подобию DbContext.OnModelCreating()
Везде использовал один и тот же общий DbContext, у которого в OnModelCreating вызывал бы настроечные методы от плагинов
Для обращения к самим сущностям использовал бы просто generic метод DbContext.Set()
Re: Entity Framework и плагинная система -- как совместить?
Здравствуйте, Shmj, Вы писали:
S>Попробовал сделать базовый DbContext, плагин наследует от него и добавляет свои таблицы (нужно отключить проверку схемы, чтобы это работало). Так каждый плагин может создавать свое подключение и использовать DbContext с новыми таблицами (которые есть только у него).
Я бы не заморачивался с наследованием. Вот тебе база — пиши туда все что хочешь и как хочешь. Возможно бы делал отдельную базу — для секурности.
S>Как лучше сделать?
А вот это уже разлуливал бы кастомным репозиторием типа
Здравствуйте, Михаил Романов, Вы писали:
МР>Ну я бы, скорее всего, делал как-то так (ранее сам не делал, просто навскидку предлагаю): МР>
МР>Для каждого плагина выделил бы какой-то метод, который будет отвечать за настройку модели. По сигнатуре можно сделать его по образу и подобию DbContext.OnModelCreating() МР>Везде использовал один и тот же общий DbContext, у которого в OnModelCreating вызывал бы настроечные методы от плагинов МР>Для обращения к самим сущностям использовал бы просто generic метод DbContext.Set() МР>
Это будет работать при одном условии: после подключения нового плагина, базу данных нужно пересоздать заново.
Как бы сделать чтобы происходило обновление схемы?
Re: Entity Framework и плагинная система -- как совместить?
Здравствуйте, Shmj, Вы писали:
S>Есть база данных. Каждый плагин имеет право создавать таблицы и чего-нибудь там хранить.
Я бы сделал сильно проще.
Не надо никаких контекстов передавать и наследовать. Передавайте строку соединения. Всё. Теперь каждый плагин это как просто самостоятельная программа, которая не зависит от других (в контексте обсуждения БД). И нет проблем.
Здравствуйте, liiw, Вы писали:
L>Я бы сделал сильно проще. L>Не надо никаких контекстов передавать и наследовать. Передавайте строку соединения. Всё. Теперь каждый плагин это как просто самостоятельная программа, которая не зависит от других (в контексте обсуждения БД). И нет проблем.
Вот только если нескольким плагинам понадобится отработать в одной транзакции ..
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
Здравствуйте, 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, то мы увидим, что по сути там происходит формирование списка из операций изменения базы.
Поэтому, чтобы сильно не ломать схему, можно попробовать сделать так:
Вы создаете свой базовый класс миграции (типа PluginMigration), который будет содержать похожие методы с DbMigration (те же AddTable, ...). Внутри же эти методы просто дергают аналогичные от DbMigration (т.е. это просто обертка)
Каждый плагин должен иметь свой класс миграции, наследник от PluginMigration
Для осуществления собственно миграции у вас используется собственный класс CompozedMigration, наследник от DbMigration, который собирает миграции от плагинов.
Скорее всего, помимо класса миграции придется что-то еще сделать с DbMigrationsConfiguration (т.к. вы собираете конфигурацию "на лету" у вас должен формироваться некий суррогатный номер версии базы).
Re[3]: Entity Framework и плагинная система -- как совместить?
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, liiw, Вы писали:
L>>Я бы сделал сильно проще. L>>Не надо никаких контекстов передавать и наследовать. Передавайте строку соединения. Всё. Теперь каждый плагин это как просто самостоятельная программа, которая не зависит от других (в контексте обсуждения БД). И нет проблем.
AVK>Вот только если нескольким плагинам понадобится отработать в одной транзакции ..
TransactionScope, или как там его зовут?
Re[4]: Entity Framework и плагинная система -- как совместить?