首页 文章

将MyDbContext与IdentityDbContext合并

提问于
浏览
48

我在一个单独的Data Accass Layer类库项目中有一个MyDbContext . 我有一个带有默认IdentityDbContext的ASP.NET MVC 5项目 . 这两个上下文使用相同的数据库,我想将AspNetUsers表用于我的表的外键 . 所以我想合并两个Context,我也想使用ASP.NET Identity .

我怎样才能做到这一点?

请指教,

合并后这是我的上下文:

public class CrmContext : IdentityDbContext<CrmContext.ApplicationUser> //DbContext
{
    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; }
    }

    public CrmContext()
        : base("DefaultConnection")
    {

    }

    public DbSet<Case> Case { get; set; }
    public DbSet<CaseLog> CaseLog { get; set; }
    public DbSet<Comment> Comment { get; set; }
    public DbSet<Parameter> Parameter { get; set; }
    public DbSet<Sign> Sign { get; set; }
    public DbSet<Template> Template { get; set; }
    public DbSet<Read> Read { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

这是我的RepositoryBase类:

public class RepositoryBase<TContext, TEntity> : IRepositoryBaseAsync<TEntity>, IDisposable
        where TContext : IdentityDbContext<CrmContext.ApplicationUser> //DbContext
        where TEntity : class
    {
        private readonly TContext _context;
        private readonly IObjectSet<TEntity> _objectSet;

        protected TContext Context
        {
            get { return _context; }
        }

        public RepositoryBase(TContext context)
        {
            if (context != null)
            {
                _context = context;
                //Here it is the error:
                _objectSet = (_context as IObjectContextAdapter).ObjectContext.CreateObjectSet<TEntity>();
             }
             else
             {
                 throw new NullReferenceException("Context cannot be null");
             }
         }
     }

EntityFramework.dll中出现 'System.Data.Entity.ModelConfiguration.ModelValidationException' 类型的异常,但未在用户代码中处理

Additional information :在模型生成期间检测到一个或多个验证错误:

Update: I found the solution.

我不得不删除这个命名约定:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}

并将ef cf模型迁移到db,使用asp.net标识的命名约定重命名我的表 . 它现在正在运作!

7 回答

  • 0
    • ApplicationUser 定义移动到DAL .

    • IdentityDbContext<ApplicationUser>IdentityDbContext 继承 MyDbContext

    • OnModelCreating - 提供外键信息 .

    • 创建 UserManager<ApplicationUser> 时传递 MyDbContext

  • -2

    如果您按照上述步骤操作但无法确定如何提供密钥信息,则可能会收到以下消息 . 您可能收到的错误是:

    IdentityUserLogin :: EntityType'IdentityUserLogin'没有定义键 . 定义此EntityType的键 . Context.IdentityUserRole :: EntityType'IdentityUserRole'没有定义键 . 定义此EntityType的键 .

    创建以下两个类

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

    在Applications DbContext中的OnModelCreating方法中,将上面概述的两个配置添加到模型中:

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

    现在,这应该在创建模型时摆脱错误方法 . 它对我有用 .

  • 6

    这可能是一个旧线程,但本文非常有助于演示如何使上述问题的解决方案有效:http://blogs.msdn.com/b/webdev/archive/2014/03/20/test-announcing-rtm-of-asp-net-identity-2-0-0.aspx

    我最终不得不包括在内

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

    因为没有它,我会得到以下错误:

    EntityType'IdentityUserRole'没有定义键 . 定义此EntityType的键 . EntityType'IdentityUserLogin'没有定义键 . 定义此EntityType的键 . EntitySet'IdentityUserRoles'基于类型'IdentityUserRole',没有定义键 . EntitySet'IdentityUserLogins'基于没有定义键的类型'IdentityUserLogin' .

    如果我添加如上所述的这些配置:

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

    它会创建一个名为Application_User的附加外键 .

  • 4

    1)从IdentityDbContext继承上下文后,与Identity表(AspNetUsers等)上的主键相关的错误应该消失 .

    2)IdentityUser的ApplicationUser扩展缺少实体框架解释为外键的导航属性(这些对于从代码导航也非常有用) .

    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)我在许多地方读到,当覆盖OnModelCreating时,你必须调用基本方法 . 似乎有时你可以没有它 .

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

    我已经对这个问题给出了完整的答案here . 这是简短的回答:

    基于IdentityDbContext源代码,如果我们想将IdentityDbContext与我们的DbContext合并,我们有两个选择:

    First Option:
    创建一个DbContext,它继承自IdentityDbContext并可以访问这些类 .

    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: (不推荐)
    如果我们自己编写所有代码,我们实际上不必继承IdentityDbContext .
    所以基本上我们可以继承DbContext并从IdentityDbContext source code实现"OnModelCreating(ModelBuilder builder)"的自定义版本

  • 28

    问题是由于您覆盖了在IdentityUser类中实现的方法“OnModelCreating”的内容而导致的 .

    您需要首先从基类调用OnModelCreating方法,然后添加您的代码 . 所以你的方法OnModelCreating应该是这样的:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
         base.OnModelCreating(modelBuilder);
    
         modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
    
  • 0

    我尝试了一种简单的方法..从数据库中复制连接字符串并替换DefaultConnection的连接字符串 . 继续创建用户,在数据库中自动创建所有必需的表 .

    希望有所帮助

相关问题