Страницы

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

среда, 5 декабря 2018 г.

Переместить таблицы в другую бд с использованием EF Code First

Есть две базы данных интернет-магазина: Одна основная (контекст наследуется от DbContext), другая содержит пользователей (ApplicationDbContext, наследуется от IdentityDbContext). На обеих настроены миграции, которые произвожу раздельно (по этому гайду).
Сегодня столкнулся с необходимостью объединить их в одну БД (хостинг ограничивает количество баз), в связи с чем появился вопрос: Как переместить все, например, в основную базу правильно, не нарушив "гомеостаз" EF Code First Migrations и Asp.Net Identity? Получится ли объединить контексты, учитывая, что они наследуются от разных классов? Что делать дальше? Или все обстоит намного проще (например 2 контекста в одной БД)? Прошу пошагово расписать если не действия, то хотя бы логику процесса, который мне необходимо проделать для решения проблемы.
P.S.: Магазин только пишется, пользователь всего 1, так что пересоздание таблицы с пользователями не страшно. Лишь бы на выходе все работало.
UPD:
Прикрепляю класс основного контекста по просьбе @Bald:
public class ProductContext : DbContext { public DbSet Products { get; set; } public DbSet Categories { get; set; } public DbSet ProductTypes { get; set; } public DbSet TopNotes { get; set; } public DbSet HeartNotes { get; set; } public DbSet BaseNotes { get; set; } public DbSet Features { get; set; } public DbSet ProductValues { get; set; } public DbSet Variations { get; set; } public DbSet Visitors { get; set; } public DbSet Carts { get; set; } public DbSet Orders { get; set; } public DbSet OrderDetails { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity().HasMany(c => c.ProductTypes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("ProductTypeId") .ToTable("Product_ProductTypes"));
modelBuilder.Entity().HasMany(c => c.TopNotes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("TopNoteId") .ToTable("Product_TopNotes"));
modelBuilder.Entity().HasMany(c => c.HeartNotes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("HeartNoteId") .ToTable("Product_HeartNotes"));
modelBuilder.Entity().HasMany(c => c.BaseNotes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("BaseNoteId") .ToTable("Product_BaseNotes"));
modelBuilder.Entity().HasMany(c => c.ProductValues) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("ProductValueId") .ToTable("Product_ProductValues")); } }
и класс ApplicationDbContext, на всякий случай:
public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext() : base("ApplicationDbContext", throwIfV1Schema: false) { }
public static ApplicationDbContext Create() { return new ApplicationDbContext(); } }


Ответ

Решил задачу переносом основного контекста в ApplicationDbContext (спасибо @Bald).
После такого объединения контекстов, при попытке провести Code First Migrations консоль выдала ошибку:
"One or more validation errors were detected during model generation: Ciel2.Models.IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType. Ciel2.Models.IdentityUserLogin: : EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType. IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined. IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no keys defined."
После нескольких дней поисков, нашел ответ тут: https://stackoverflow.com/questions/19994590/asp-net-identity-validation-error
Суть проблемы вкратце (а также решение): Наличие в контексте данных сущностей, связанных отношением многие-ко-многим, вынуждает к переопределению метода OnModelCreating (что отражено в моем коде). Таким образом для корректной работы объединенных контекстов необходимо приписать:
base.OnModelCreating(modelBuilder);
непосредственно перед основным содержанием метода. После этих изменений миграция заработала и никаких проблем с Entity Framework больше не возникает. Полностью мой окончательный контекст данных выглядит так (не обращайте внимание на разницу в сущностях, за время работы он немного вырос):
public class ApplicationUser : IdentityUser { public string FirstName { get; set; } public ICollection

Addresses { get; set; } public string AvatarUrl { get; set; }
public ApplicationUser() { Addresses = new List
(); }
public async Task GenerateUserIdentityAsync(UserManager manager) { var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity; } }
public class ApplicationDbContext : IdentityDbContext { public DbSet Products { get; set; } public DbSet Categories { get; set; } public DbSet ProductTypes { get; set; } public DbSet TopNotes { get; set; } public DbSet HeartNotes { get; set; } public DbSet BaseNotes { get; set; } public DbSet Features { get; set; } public DbSet ProductValues { get; set; } public DbSet Variations { get; set; } public DbSet Visitors { get; set; } public DbSet Carts { get; set; } public DbSet Favs { get; set; } public DbSet Orders { get; set; } public DbSet OrderDetails { get; set; } public DbSet
Addresses { get; set; } public DbSet OrderStatuses { get; set; } public DbSet Pictures { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // та самая строка кода
modelBuilder.Entity().HasMany(c => c.ProductTypes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("ProductTypeId") .ToTable("Product_ProductTypes"));
modelBuilder.Entity().HasMany(c => c.TopNotes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("TopNoteId") .ToTable("Product_TopNotes"));
modelBuilder.Entity().HasMany(c => c.HeartNotes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("HeartNoteId") .ToTable("Product_HeartNotes"));
modelBuilder.Entity().HasMany(c => c.BaseNotes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("BaseNoteId") .ToTable("Product_BaseNotes"));
modelBuilder.Entity().HasMany(c => c.ProductValues) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("ProductValueId") .ToTable("Product_ProductValues")); }
public ApplicationDbContext() : base("ApplicationDbContext", throwIfV1Schema: false) {
}
public static ApplicationDbContext Create() { return new ApplicationDbContext(); } }
Еще раз большое спасибо пользователю @Bald и сайту StackOverflow за помощь в решении задачи.

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

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