UserManager.CreateAsync不生成Id

时间:2014-06-17 20:10:08

标签: c# asp.net-mvc entity-framework asp.net-identity-2

我刚刚将我的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>

3 个答案:

答案 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设计器

aspNetUserClaims designer

如果将此处的UserId字段更改为uniqueIdentifier,它将同时级联并更改其他表中的数据类型,一直返回到AspNetUsers。

aspNetUserClaims uniqueIdentifier