与IdentityDbContext合并MyDbContext
我有一个分离的Data Accass Layer类库项目中的MyDbContext。 我有一个默认的IdentityDbContext的ASP.NET MVC 5项目。 这两个上下文使用相同的数据库,我想使用AspNetUsers表来外键为我的一些表。 所以我想合并这两个上下文,我也想使用ASP.NET身份。
我该怎么做?
请指教,
合并后,这是我的上下文:
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'
types的exception,但未在用户代码中处理
附加信息 :在模型生成过程中检测到一个或多个validation错误:
更新:我find了解决scheme。
我不得不删除这个命名约定:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); }
并将ef cf模型迁移到db,以asp.net标识的命名约定来重命名我的表。 它正在工作!
- 将
ApplicationUser
定义移动到您的DAL。 - 从
IdentityDbContext<ApplicationUser>
或IdentityDbContext
inheritanceMyDbContext
- OnModelCreating – 提供外键信息。
- 在创build
UserManager<ApplicationUser>
传递MyDbContext
如果按照上述步骤操作,可能会收到以下消息,但无法提供关键信息。 您可能收到的错误是:
IdentityUserLogin :: EntityType“IdentityUserLogin”没有定义密钥。 定义这个EntityType的关键。 Context.IdentityUserRole::EntityType'IdentityUserRole'没有定义密钥。 定义这个EntityType的关键。
创build以下两个类
public class IdentityUserLoginConfiguration : EntityTypeConfiguration<IdentityUserLogin> { public IdentityUserLoginConfiguration() { HasKey(iul => iul.UserId); } } public class IdentityUserRoleConfiguration : EntityTypeConfiguration<IdentityUserRole> { public IdentityUserRoleConfiguration() { HasKey(iur => iur.RoleId); } }
在应用程序DbContext的OnModelCreating方法中,将上面概述的两种configuration添加到模型中:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new IdentityUserLoginConfiguration()); modelBuilder.Configurations.Add(new IdentityUserRoleConfiguration()); }
现在应该在创build模型时摆脱错误方法。 它为我做了。
这可能是一个古老的线程,但是这篇文章是非常有用的演示如何得到解决上述问题的工作: http : //blogs.msdn.com/b/webdev/archive/2014/03/20/test-宣布-RTM-的-ASP净身份2-0-0.aspx
我已经结束了不得不包括
protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); //.... }
因为没有它,我会得到以下错误:
EntityType'IdentityUserRole'没有定义键。 定义这个EntityType的关键。 EntityType“IdentityUserLogin”没有定义密钥。 定义这个EntityType的关键。 EntitySet“IdentityUserRoles”基于没有定义键的types“IdentityUserRole”。 EntitySet'IdentityUserLogins'基于没有定义键的'IdentityUserLogin'types。
如果我像上面提到的那样添加这些configuration:
public class IdentityUserLoginConfiguration : EntityTypeConfiguration<IdentityUserLogin> { public IdentityUserLoginConfiguration() { HasKey(iul => iul.UserId); } } public class IdentityUserRoleConfiguration : EntityTypeConfiguration<IdentityUserRole> { public IdentityUserRoleConfiguration() { HasKey(iur => iur.RoleId); } }
它会创build一个名为Application_User的额外的外键。
1)inheritanceIdentityDbContext的上下文后,与Identity表上的主键(AspNetUsers等)相关的错误应该消失。
2)您的IdentityUser的ApplicationUser扩展缺less由Entity Framework解释为外键的导航属性(这些对于从您的代码导航也非常有用)。
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); //.... }
我已经在这里给出了这个问题的完整答案。 这里是简短的答案:
基于IdentityDbContext源代码,如果我们想将IdentityDbContext与我们的DbContext合并,我们有两个select:
第一个选项:
创build一个inheritance自IdentityDbContext的DbContext,并有权访问这些类。
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 }
第二个选项:(不推荐)
如果我们自己编写所有的代码,我们实际上不必从IdentityDbContextinheritance。
所以基本上,我们可以从DbContextinheritance,并从IdentityDbContext源代码实现我们自定义版本的“OnModelCreating(ModelBuilder builder)”
我尝试了一个简单的方法..从您的数据库复制连接string,并replaceDefaultConnection的连接string。 继续创build用户,所有必要的表格都会自动在您的数据库中创build。
希望有所帮助