对于我的Web应用程序,我使用代码优先方法,但所有与数据库访问相关的代码都驻留在不同的项目(Infrastructure)中。默认情况下,Web项目中的所有ASP.NET标识都是。我知道我可以通过更改连接字符串将ASP.NET Identity指向现有数据库:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("MyDatabase", throwIfV1Schema: false)
{
}
...
}
然而,调用AccountController会给我一个错误:
InvalidOperationException:实体类型ApplicationUser不是当前上下文模型的一部分。
登录时出现错误
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
并且堆栈跟踪显示
System.Data.Entity.Internal.InternalContext.UpdateEntitySetMappingsForType(Type entityType)+137 System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)+36 System.Data.Entity.Internal.Linq.InternalSet
1.Initialize() +79 System.Data.Entity.Internal.Linq.InternalSet
1.get_InternalContext()+28 System.Data.Entity.Infrastructure.DbQuery1.System.Linq.IQueryable.get_Provider() +56 System.Data.Entity.QueryableExtensions.FirstOrDefaultAsync(IQueryable
1个来源,表达式1 predicate, CancellationToken cancellationToken) +127 System.Data.Entity.QueryableExtensions.FirstOrDefaultAsync(IQueryable
1个来源,表达式1 predicate) +156 Microsoft.AspNet.Identity.EntityFramework.<GetUserAggregateAsync>d__6c.MoveNext() +468 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 System.Runtime.CompilerServices.TaskAwaiter
1.GetResult()+28 Microsoft.AspNet.Identity.CultureAwaiter`1.GetResult()+ 75 Microsoft.AspNet.Identity.Owin.d__29.MoveNext()+ 361
使用SQL Server Management Studio查看数据库我可以看到尚未创建Identity的表,所以现在我想知道究竟是什么触发了所需表的创建。任何想法或指针?
答案 0 :(得分:0)
查看这篇文章:
使用数据库优先设置ASP.NET Identity Framework 2.0
它帮助我在我自己的数据库中实现了Identity Framework
答案 1 :(得分:0)
在研究了ASP.NET Identity v2的源代码之后,想出了我自己的解决方案。问题 - 在我的情况下无论如何 - 是DbContext在一个不同于web项目的项目中。但是,由于ASP.NET Identity使用自己的继承自IdentityDbContext<TUser>
的上下文,因此从未应用该上下文的映射,因此它开始在上下文中查找ApplicationUser
,而这种情况并不存在,当然。这就是错误信息的全部内容。
以下是从ASP.NET IdentityDbContext
获取的代码段:
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<TUser>(b =>
{
b.HasKey(u => u.Id);
b.HasIndex(u => u.NormalizedUserName).HasName("UserNameIndex");
b.HasIndex(u => u.NormalizedEmail).HasName("EmailIndex");
b.ToTable("AspNetUsers");
...
}
}
因此,用户类型(例如ApplicationUser
)将映射到数据库中的AspNetUsers
,这意味着您看到错误消息的那一刻
InvalidOperationException:实体类型ApplicationUser不是当前上下文模型的一部分。
这表示IdentityDbContext
的映射未应用,您正在查询ApplicationUser
而不是AspNetUsers
。
我的解决方案是创建一个单独的文件夹,其中包含身份上下文及其迁移:
然后我就可以通过发布来创建数据库及其所有表,包括ASP.NET身份表
PM> update-database -ConfigurationTypeName BlogContextConfiguration
PM> update-database -ConfigurationTypeName PortalContextConfiguration
无需人工干预,SQL脚本等。
这也可能适用于现有的数据库,但我还没有检查过,所以要小心。