Есть две базы данных интернет-магазина: Одна основная (контекст наследуется от 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
Комментариев нет:
Отправить комментарий