There are two online store databases: One main (context inherits from DbContext ), the other contains users ( ApplicationDbContext , inherited from IdentityDbContext<ApplicationUser> ). Both are configured with migrations that I produce separately (according to this guide ).

Today I faced the need to combine them into one database (hosting limits the number of bases), and therefore the question arose: How to move everything, for example, to the main database correctly, without breaking the EF Code First Migrations and Asp.Net Identity "homeostasis"? Will it be possible to combine contexts, given that they are inherited from different classes? What to do next? Or is everything much simpler (for example, 2 contexts in one database)? I ask you step by step to paint, if not actions, then at least the logic of the process that I need to do to solve the problem.

PS: The store is only written, the user is only 1, so the re-creation of the table with users is not scary. If only the output worked.

UPD:

Attaching the main context class at the request of @Bald:

 public class ProductContext : DbContext { public DbSet<Product> Products { get; set; } public DbSet<Category> Categories { get; set; } public DbSet<ProductType> ProductTypes { get; set; } public DbSet<TopNote> TopNotes { get; set; } public DbSet<HeartNote> HeartNotes { get; set; } public DbSet<BaseNote> BaseNotes { get; set; } public DbSet<Feature> Features { get; set; } public DbSet<ProductValue> ProductValues { get; set; } public DbSet<Variation> Variations { get; set; } public DbSet<Visitor> Visitors { get; set; } public DbSet<Cart> Carts { get; set; } public DbSet<Order> Orders { get; set; } public DbSet<OrderDetail> OrderDetails { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Product>().HasMany(c => c.ProductTypes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("ProductTypeId") .ToTable("Product_ProductTypes")); modelBuilder.Entity<Product>().HasMany(c => c.TopNotes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("TopNoteId") .ToTable("Product_TopNotes")); modelBuilder.Entity<Product>().HasMany(c => c.HeartNotes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("HeartNoteId") .ToTable("Product_HeartNotes")); modelBuilder.Entity<Product>().HasMany(c => c.BaseNotes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("BaseNoteId") .ToTable("Product_BaseNotes")); modelBuilder.Entity<Product>().HasMany(c => c.ProductValues) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("ProductValueId") .ToTable("Product_ProductValues")); } } 

and the ApplicationDbContext class, just in case:

 public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public ApplicationDbContext() : base("ApplicationDbContext", throwIfV1Schema: false) { } public static ApplicationDbContext Create() { return new ApplicationDbContext(); } } 
  • @Bald It was disturbed that the language is still a relative newcomer. I can’t say that I didn’t think about this exit, but I stopped the fear of changing something connected with identity, because I’m not very familiar with it and the chance to break something is great. Could you describe a sequence of actions that will help me transfer the identity context to the main one and fully work with the resulting context without swearing at EF Code First (I had a lot of trouble with it in my time as with a child) and, let's say, not to miss any tails? - Denis Kutovskiy
  • @Bald Not yet understood this topic. Of course, I plan to use it, but at this stage I use only the default ASP.NET Identity authorization. This is an authorization on the site (1 user - it is assumed that the buyer - to check the filters and other things). Admin is still without authorization (there is still to learn the logic of roles, clauses, etc.). So identity is as close as possible to the original when creating the application, as far as I can tell. - Denis Kutovskiy
  • @Bald that is to transfer the main context to public class ApplicationDbContext : IdentityDbContext<ApplicationUser> ? I did not understand what public DbSet<History> Histories {get;set;} . - Denis Kutovskiy
  • add to the original question your class which you call the main context, i.e. one that inherits from DbContext - Bald
  • one
    I found a solution here: stackoverflow.com/questions/19994590/… . Thanks @Bald for your time. - Denis Kutovskiy

1 answer 1

Solved the problem by transferring the main context to ApplicationDbContext (thanks to @Bald).

After such a union of contexts, when trying to run Code First Migrations, the console issued an error:

 "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." 

After several days of searching, I found the answer here: https://stackoverflow.com/questions/19994590/asp-net-identity-validation-error .

The essence of the problem in brief (and also the solution): The presence in the context of these entities, connected by a many-to-many relationship, forces us to redefine the OnModelCreating method (which is reflected in my code). Thus, for the correct operation of the combined contexts, it is necessary to attribute:

base.OnModelCreating(modelBuilder);

immediately before the main content of the method. After these changes, the migration is working and no problems with the Entity Framework arise anymore. Completely my final data context looks like this (do not pay attention to the difference in the entities, it has grown a bit during the work):

 public class ApplicationUser : IdentityUser { public string FirstName { get; set; } public ICollection<Address> Addresses { get; set; } public string AvatarUrl { get; set; } public ApplicationUser() { Addresses = new List<Address>(); } public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) { var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); return userIdentity; } } public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public DbSet<Product> Products { get; set; } public DbSet<Category> Categories { get; set; } public DbSet<ProductType> ProductTypes { get; set; } public DbSet<TopNote> TopNotes { get; set; } public DbSet<HeartNote> HeartNotes { get; set; } public DbSet<BaseNote> BaseNotes { get; set; } public DbSet<Feature> Features { get; set; } public DbSet<ProductValue> ProductValues { get; set; } public DbSet<Variation> Variations { get; set; } public DbSet<Visitor> Visitors { get; set; } public DbSet<Cart> Carts { get; set; } public DbSet<Fav> Favs { get; set; } public DbSet<Order> Orders { get; set; } public DbSet<OrderDetail> OrderDetails { get; set; } public DbSet<Address> Addresses { get; set; } public DbSet<OrderStatus> OrderStatuses { get; set; } public DbSet<Picture> Pictures { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // та самая строка кода modelBuilder.Entity<Product>().HasMany(c => c.ProductTypes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("ProductTypeId") .ToTable("Product_ProductTypes")); modelBuilder.Entity<Product>().HasMany(c => c.TopNotes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("TopNoteId") .ToTable("Product_TopNotes")); modelBuilder.Entity<Product>().HasMany(c => c.HeartNotes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("HeartNoteId") .ToTable("Product_HeartNotes")); modelBuilder.Entity<Product>().HasMany(c => c.BaseNotes) .WithMany(s => s.Products) .Map(t => t.MapLeftKey("ProductId") .MapRightKey("BaseNoteId") .ToTable("Product_BaseNotes")); modelBuilder.Entity<Product>().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(); } } 

Thanks again to @Bald and StackOverflow for helping to solve the problem.