Merge MyDbContext with IdentityDbContext

前端 未结 8 1811
天命终不由人
天命终不由人 2020-11-28 22:22

I have a MyDbContext in a separated Data Accass Layer class library project. And I have an ASP.NET MVC 5 project with a default IdentityDbContext. The two context use the sa

相关标签:
8条回答
  • 2020-11-28 22:56

    You may get the following message if you follow the above steps but can't work out how to provide the key information. The error you may receive is:

    IdentityUserLogin: : EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType. Context.IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType.

    Create the two following classes

    public class IdentityUserLoginConfiguration : EntityTypeConfiguration<IdentityUserLogin>
    {
    
        public IdentityUserLoginConfiguration()
        {
            HasKey(iul => iul.UserId);
        }
    
    }
    
    public class IdentityUserRoleConfiguration : EntityTypeConfiguration<IdentityUserRole>
    {
    
        public IdentityUserRoleConfiguration()
        {
            HasKey(iur => iur.RoleId);
        }
    
    }
    

    In the OnModelCreating method within your Applications DbContext add the two configurations outlined above to the model:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
    
            modelBuilder.Configurations.Add(new IdentityUserLoginConfiguration());
            modelBuilder.Configurations.Add(new IdentityUserRoleConfiguration());
    
        }
    

    This should now get rid of the error methods when your model is being created. It did for me.

    0 讨论(0)
  • 2020-11-28 22:59
    1. Move the ApplicationUser definition to your DAL.
    2. Inherit your MyDbContext from IdentityDbContext<ApplicationUser> or IdentityDbContext
    3. OnModelCreating - Provide the foreign key info.
    4. Pass MyDbContext while creating the UserManager<ApplicationUser>
    0 讨论(0)
  • 2020-11-28 23:04

    1) After you inherit the context from IdentityDbContext errors related to primary keys on the Identity tables (AspNetUsers etc) should disappear.

    2) Your ApplicationUser extension of IdentityUser is missing navigation properties that are interpreted as foreign keys by the Entity Framework (these are also very useful for navigation from your code).

    public class ApplicationUser : IdentityUser
    {
        public Int16 Area { get; set; }
        public bool Holiday { get; set; }
        public bool CanBePublic { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    
        //*** Add the following for each table that relates to ApplicationUser (here 1-to-many)
        public virtual IList<Case> Cases { get; set; } //Navigation property
        //*** and inside the case class you should have 
        //*** both a public ApplicationUser ApplicationUser {get;set;}
        //*** and a public string ApplicationUserId {get;set;} (string because they use GUID not int)
    }
    

    3) I read in many places that when overiding OnModelCreating, you have to call the base method. It seems that sometimes you can do without it.

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
             base.OnModelCreating(modelBuilder);
             //....
        }
    
    0 讨论(0)
  • 2020-11-28 23:09

    It's worth noting that if you merge the DBContexts you are tying an authentication approach (ASP's Identity in this case) to the data access implementation (EF). From a code design point of view that could be seen as mixing your concerns and a violation of Single Responsibility Principle.

    That's probably fine in the majority of cases, but if you want to reuse your data layer in other non-web applications (e.g. for a desktop or server app) this will present an issue because IdentityDbContext lives in the Microsoft.AspNet.Identity.EntityFramework namespace and your desktop or server apps are unlikely to be using AspNet Identity as their authentication mechanism.

    We were in that situation and ended up keeping ASP's second DB Context, which stayed in the web project. We then cross-loaded some of the data about the user (first name, last name, etc.) into the Identity's claims object when the user signed in.

    0 讨论(0)
  • 2020-11-28 23:10

    I have given a complete answer to this question here. Here is the short answer:

    Based on IdentityDbContext source code if we want to merge IdentityDbContext with our DbContext we have two options:

    First Option:
    Create a DbContext which inherits from IdentityDbContext and have access to the classes.

       public class ApplicationDbContext 
        : IdentityDbContext
    {
        public ApplicationDbContext()
            : base("DefaultConnection")
        {
        }
    
        static ApplicationDbContext()
        {
            Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
        }
    
        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    
        // Add additional items here as needed
    }
    

    Second Option:(Not recommended)
    We actually don't have to inherit from IdentityDbContext if we write all the code ourselves.
    So basically we can just inherit from DbContext and implement our customized version of "OnModelCreating(ModelBuilder builder)" from the IdentityDbContext source code

    0 讨论(0)
  • 2020-11-28 23:13

    This may be an old thread, but this article was very helpful in demonstrating how to get the solution to the above question working: http://blogs.msdn.com/b/webdev/archive/2014/03/20/test-announcing-rtm-of-asp-net-identity-2-0-0.aspx

    I did end having to include

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
         base.OnModelCreating(modelBuilder);
         //....
    }
    

    because without it, I would get the following error:

    EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType. EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType. EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined. EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no keys defined.

    If I add these configurations as mentioned above:

    public class IdentityUserLoginConfiguration : EntityTypeConfiguration<IdentityUserLogin>
    {
        public IdentityUserLoginConfiguration()
        {
            HasKey(iul => iul.UserId);
        }
    }
    
    public class IdentityUserRoleConfiguration : EntityTypeConfiguration<IdentityUserRole>
    {
        public IdentityUserRoleConfiguration()
        {
            HasKey(iur => iur.RoleId);
        }
    }
    

    it would create an additional foreign key called Application_User.

    0 讨论(0)
提交回复
热议问题