由于重命名的 AspNetUserRoles 列,ASP.NET Identity Model First 失败
Posted
技术标签:
【中文标题】由于重命名的 AspNetUserRoles 列,ASP.NET Identity Model First 失败【英文标题】:ASP.NET Identity Model First fails because of renamed AspNetUserRoles columns 【发布时间】:2014-09-06 15:33:06 【问题描述】:与其他几个人一样,我首先尝试实现 ASP.NET 身份模型。一旦你尝试过、出错、发怒、搜索和解决,一切都很好。我想。
另见:
ASP.NET Identity with EF Database First MVC5 http://danieleagle.com/blog/2014/05/setting-up-asp-net-identity-framework-2-0-with-database-first-vs2013-update-2-spa-template/行动路线,总结:
已创建默认项目 (MVC5) 创建数据库 更新 web.config 中的连接字符串 运行网站,注册:创建表 创建 EF 模型 (edmx) 导入身份表(到目前为止一切正常) 修改 xxx.Context.tt 以从 IdentityDbContext 继承 生成数据库脚本(问题从这里开始)我已经解决了出现的问题(直到最后一步)。为了完整起见,我将描述它们。
使用默认身份上下文
一切正常:创建表,我可以注册和登录。然而,这不是我想要的情况:我想使用 Model First 方法。
使用自定义的模型优先上下文,使用 EF 连接字符串
修改 CreatePerOwinContext 使其使用我的 Model First 上下文:
public void ConfigureAuth(IAppBuilder app)
app.CreatePerOwinContext(CustomModelFirstDbContext.Create);
还有 ApplicationUserManager 以便它使用 Model First 上下文:
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<CustomModelFirstDbContext>()));
结果:
“/”应用程序中的服务器错误。
实体类型 ApplicationUser 不是模型的一部分 当前上下文。
描述:执行过程中发生了未处理的异常 当前的网络请求。请查看堆栈跟踪以获取更多信息 有关错误的信息以及它在代码中的来源。
异常详细信息:System.InvalidOperationException:实体类型 ApplicationUser 不是当前上下文模型的一部分。
来源错误:
在执行过程中产生了一个未处理的异常 当前的网络请求。有关原产地和位置的信息 可以使用下面的异常堆栈跟踪来识别异常。
堆栈跟踪: [InvalidOperationException:实体类型 ApplicationUser 不是 当前上下文的模型的一部分。]
在自定义的模型优先上下文中使用“普通”连接字符串
类型异常 'System.Data.Entity.Infrastructure.UnintentionalCodeFirstException' 发生在 WebApplication1.dll 中,但未在用户代码中处理
附加信息:使用 T4 模板生成的代码 数据库优先和模型优先开发可能无法正常工作,如果 用于代码优先模式。继续使用 Database First 或 Model 首先确保指定了实体框架连接字符串 在执行应用程序的配置文件中。要使用这些类, 从 Database First 或 Model First 生成的,带有代码 首先使用属性或 DbModelBuilder API,然后删除引发此问题的代码 例外。
所以,我认为我需要默认的 Identity 上下文来使用 Identity,并使用自定义的 Model First 上下文来处理其他所有内容。不是首选解决方案,但可以接受。
回滚所有内容 从数据库中导入身份表 (可选)通过模型优先方法创建的实体 生成的数据库脚本普通项目和快速健全性检查测试项目都存在与 AspNetUserRoles 表相同的问题。那是一个联结表,在 EF 设计器中导入时,一切正常。您不会看到它,因为它是多对多关系,并且在检查 AspNetRole 和 AspNetUser 之间的关联时,它看起来不错。
设计师和映射细节:
但是,在生成 sql 脚本时,EF 会修改键。
设计师和映射细节:
生成的 SQL 脚本:
-- Creating table 'AspNetUserRoles'
CREATE TABLE [dbo].[AspNetUserRoles] (
[AspNetRoles_Id] nvarchar(128) NOT NULL,
[AspNetUsers_Id] nvarchar(128) NOT NULL
);
GO
在 EF 中,您无法在设计器 (thread on social.msdn.microsoft.com) 中更改映射的名称。
随后使用最初创建的上下文创建新用户将失败,因为联结表包含错误的列:
“/”应用程序中的服务器错误。
列名“UserId”无效。
列名“UserId”无效。
列名“UserId”无效。
列名“RoleId”无效。
列名“UserId”无效。
描述:执行过程中发生了未处理的异常 当前的网络请求。请查看堆栈跟踪以获取更多信息 有关错误的信息以及它在代码中的来源。
异常详细信息:System.Data.SqlClient.SqlException:列名“UserId”无效。列名“用户 ID”无效。列名“用户 ID”无效。列名“RoleId”无效。列名“UserId”无效。
来源错误:
第 89 行:
第 90 行:var user = new ApplicationUser() UserName = model.Email, Email = model.Email ;
第 91 行:IdentityResult 结果 = await UserManager.CreateAsync(user, model.Password);
第 92 行:if (result.Succeeded)
第 93 行:
解决办法是什么?除了尝试更改生成的脚本或迁移到 Code First 之外,还有其他选择吗?
【问题讨论】:
我在博客的 cmets 中回答了这个问题。有关更多详细信息,请参阅(danieleagle.com/blog/2014/05/setting-up-asp-net-identity-framework-2-0-with-database-first-vs2013-update-2-spa-template/) .如果您对我的建议有任何运气,我可以将它们发布为这个问题的答案。我想首先确保它有用,以便社区的其他人受益。 感谢您的详细回复。如果我可以总结一下,您是在说:(1)使用 Model First 来设计实体和数据库创建脚本(2)使用从 Code First 生成的 SQL 脚本来创建 Identity 表和关系(3)不要使用 Model First 方法设计任何与身份相关的东西?这对我来说意味着 Identity and Model First 功能不全,需要一种解决方法(如你的)。 是的,没错。这是我目前的理解水平。我很高兴知道是否还有其他方法。现实情况是 Identity Framework 2.0 的实施方式高度依赖于 Code First。因此,此时在 Code First 之外使用它需要一些技巧和使用变通方法。我希望在未来的版本中,它们会使这更容易。如果其他人知道更好的方法,我很想听听,我相信你也会。 我当然希望如此。也许像@DarinDimitrov 这样的人知道答案? :o) 为什么你觉得你绝对必须首先让你的身份上下文成为模型? 【参考方案1】:如果您在开始时 db 仍然是空的 我相信最简单的解决方法是:
-
创建 EF 模型 (edmx)。
右键单击模型“从模型生成数据库”。
它将创建 DDL 文件(下面的 sn-p)
将所有错误的“AspNetUsers_Id”和“AspNetRoles_Id”替换为正确的值。
右击“执行”。
为我工作。
-- Creating non-clustered index for FOREIGN KEY 'FK_AspNetUserRoles_AspNetUser'
CREATE INDEX [IX_FK_AspNetUserRoles_AspNetUser]
ON [dbo].[AspNetUserRoles]
([AspNetUsers_Id]); //replace for UserId
编码愉快!
【讨论】:
以上是关于由于重命名的 AspNetUserRoles 列,ASP.NET Identity Model First 失败的主要内容,如果未能解决你的问题,请参考以下文章