Страницы

Поиск по вопросам

суббота, 15 июня 2019 г.

Миграции с несколькими DbContext

Классы:
public class Document { public int Id { get; set; } public string Title { get; set; } public int UserId { get; set; }
///

/// пользователь который создал документ /// public User User { get; set; } }
public class User { public int Id { get; set; } public string UserName { get; set; } }
Два DbContext'a
public class UserContext : DbContext { public UserContext() : base ("name=ConnectionStringName") { }
static UserContext() { Database.SetInitializer(null); }
public DbSet Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.HasDefaultSchema("User"); base.OnModelCreating(modelBuilder); } }
class DocumentContext : DbContext { public DocumentContext() : base("name=ConnectionStringName") { }
static DocumentContext() { Database.SetInitializer(null); }
public DbSet Documents { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.HasDefaultSchema("Document"); modelBuilder.Entity().ToTable("Users", "User"); base.OnModelCreating(modelBuilder); } }
UserContext - хранит данные пользователей (User, Roles, ExternalLogins ...).
DocumentContext -
создаю миграцию для UserContext. В базе создается схема с нужными таблицами
создаю миграцию для DocumentContext, в методе Up EF пытоется создать таблицу которая уже существует, из-за чего я получаю ошибку:
There is already an object named 'Users' in the database.
public partial class InitialDocument : DbMigration { public override void Up() { CreateTable( "Document.Documents", c => new { Id = c.Int(nullable: false, identity: true), Title = c.String(), UserId = c.Int(nullable: false), }) .PrimaryKey(t => t.Id) .ForeignKey("User.Users", t => t.UserId, cascadeDelete: true) .Index(t => t.UserId);
//EF пытается создать таблицу в схеме User, //Но она уже создана другой миграцией (UserMigrations) //поэтому выходит ошибка - There is already an object named 'Users' in the database. //Как объяснить EF чтобы чтобы он не создавал эту таблицу? CreateTable( "User.Users", c => new { Id = c.Int(nullable: false, identity: true), UserName = c.String(), }) .PrimaryKey(t => t.Id); } //скрыто }
Вопрос - Как объяснить EF чтобы чтобы он не создавал таблицу user?
Update
Как временное решение я удаляю кусок кода который создает миграция


Ответ

Делать миграции по разным (нескольким) контекстам - не очень удобно, да и не очень хорошо. Насколько мне известно, кроме как руками фиксить данные проблемы, то есть убирать из методов Up и Down код, который Вам не нужен - не получится.
EntityFramework достаточно умен, но решить эту проблему навесив пару атрибутов или через OnModelCreating не получится (используя modelBuilder.Ignore()), хотя, может быть в скором времени EntityFramework справится с такой задачей, именно для одной базы данных.
Даже если начинает получаться что-то сделать на подобии того, что Вы хотите - столкнетесь с проблемой, которая приведет к провалу. Если убрать из классов ссылки на другие классы в свойствах - то он не будет подтягивать других таблиц, но тогда не создаст внешних ключей.
Если использовать modelBuilder.HasDefaultSchema("schema") а затем при добавлении миграции, указать полное имя Вашего класса конфигурации (полученного из DbMigrationsConfiguration) в качестве параметра в add-migration, таким образом:
add-migration NAME_OF_MIGRATION -ConfigurationTypeName FULLY_QUALIFIED_NAME_OF_CONFIGURATION_CLASS
Тоже Вам не подойдет и вряд ли поможет.
Решение данной коллизии я вижу таким: создать обобщенный контекст и выполнять миграции для одного контекста. Так Вы не потеряете изменений и будет меньше конфликтов. Ссылка из комментария - Entity Framework: One Database, Multiple DbContexts. Is this a bad idea? - очень хороший пример.
Если Ваш проект будет не слишком большим и разделение моделей будет минимальным, то этот подход будет прост. Но если у Вас будет много моделей, несколько контекстов, общие классы и наследование - то придется немного напрячься. EntityFramework очень любит наследование.

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

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