我刚刚将我的MVC 5应用程序(之前是带有SimpleMembership
的MVC 3)升级到ASP.NET Identity 2.0,我可以与现有用户一起工作,但是当我执行以下操作来创建新用户时:
var user = new ApplicationUser();
//user.Id = db.Users.Max(u => u.Id) + 1; //does not help
user.UserName = model.UserName;
user.Email = model.EMailAddress;
var result = await UserManager.CreateAsync(user, model.Password);
我得到以下内容:
System.Data.Entity.Core.UpdateException:更新条目时发生错误。有关详细信息,请参阅内部异常---> System.Data.SqlClient.SqlException:无法将值NULL插入列' Id',table' MyDB.dbo.AspNetUsers&#39 ;;列不允许空值。 INSERT失败。 声明已经终止。
有谁知道为什么会这样?
这是我的UserManager
:
var manager = new ApplicationUserManager(new ApplicationUserStore(context.Get<MyDbContext>()));
manager.UserValidator = new UserValidator<ApplicationUser, int>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = false,
RequireUppercase = false,
};
manager.EmailService = new EmailService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, int>(dataProtectionProvider.Create("ASP.NET Identity"));
}
我为用户和角色使用int
个密钥,但我之前有string
- 密钥,Id
也没有填充,我也遇到了类似的错误。< / p>
答案 0 :(得分:5)
我发现了问题:
由于我将密钥从string
更改为int
,因此创建了以下迁移:
AlterColumn("dbo.AspNetUsers", "Id", c => c.Int(nullable: false, identity: true));
它正确生成identity: true
,但MSSQL无法将现有列转换为标识列=&gt;该列成为“正常INT
列”
然后,标识必须假定该列是标识列并插入null
作为键,并期望DB生成id =&gt;异常。
解决方案是从旧备份还原到我的SimpleMembership
数据库,并在创建ASP.NET Identity
时使用int
- 键将其直接转换为AspNetUsers
- 表
P.S。:但我仍然不知道为什么我遇到与string
相似的问题 - 键,但我更喜欢int
- 键更好......
答案 1 :(得分:0)
只是遇到了这个问题,我还不清楚我在保持迁移的同时该如何解决这个问题,因此我添加了这个答案,以进一步澄清@ChrFin在他的评论中提到的内容。 / p>
如果您通过迁移从Int
切换到Guid
ID,则必须在给定迁移中进行修改,以创建不会失败的表UserManager.Create()
:< / p>
//AlterColumn("dbo.AspNetRoles", "Id", c => c.Int(nullable: false, identity: true));
DropColumn("dbo.AspNetRoles", "Id");
AddColumn("dbo.AspNetRoles", "Id", c => c.Int(nullable: false, identity: true));
// ...
//AlterColumn("dbo.AspNetUsers", "Id", c => c.Int(nullable: false, identity: true));
DropColumn("dbo.AspNetUsers", "Id");
AddColumn("dbo.AspNetUsers", "Id", c => c.Int(nullable: false, identity: true));
答案 2 :(得分:0)
从Guid(随机字符串)切换到int Id后,我遇到了同样的问题,但是我能够以其他方式解决它。我能够使用SQL Server对象资源管理器(SSOE)。我打开了SSOE,找到了我的数据库并展开了表,然后右键单击dbo.AspNetUsers> View Designer。我看到Id是一个整数,我认为是正确的,但实际上它应该是uniqueIdentifier。我试图将数据类型更改为uniqueIdentifier,但是不能。当我单击“更新”失败时,它给我一个错误消息,提示它被其他表引用为外键。我认为它列出了3个表,如果您遵循该线索,它会导引到表 dbo.AspNetUserClaims 。 aspNetUserClaims设计器
如果将此处的UserId字段更改为uniqueIdentifier,它将同时级联并更改其他表中的数据类型,一直返回到AspNetUsers。