5

我刚刚将我的 MVC 5 应用程序(以前是带有 的 MVC 3 SimpleMembership)升级到 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”、表“MyDB.dbo.AspNetUsers”中;列不允许空值。插入失败。该语句已终止。

有谁知道为什么会这样?

这是我的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-keys 并且那里Id也没有填充,我得到了类似的错误。

4

3 回答 3

7

我发现了问题:
因为我将密钥从更改stringint创建了以下迁移:

AlterColumn("dbo.AspNetUsers", "Id", c => c.Int(nullable: false, identity: true));

它在那里正确生成identity: true,但 MSSQL 无法将现有列转换为标识列 => 该列成为“普通INT列”。
然后标识必须假定该列是标识列并null作为键插入并期望数据库生成 id => 异常。

SimpleMembership解决方案是从旧备份恢复到我的数据库,并在创建 -table 时直接将其转换为ASP.NET Identity使用-key。intAspNetUsers

PS:但我仍然不知道为什么我在使用string-keys 时遇到了类似的问题,但无论如何我更喜欢int-keys ......

于 2014-06-17T21:42:09.700 回答
0

从 Guid (随机字符串)切换到 int Id 后,我遇到了同样的问题,但我能够以不同的方式解决它。我能够使用 SQL Server 对象资源管理器 (SSOE)。我打开 SSOE,找到我的数据库并展开表,然后右键单击 dbo.AspNetUsers >View Designer。我看到Id是一个int,我认为它是正确的,但实际上它应该是uniqueIdentifier。我试图将数据类型更改为 uniqueIdentifier 但不能。当我单击更新失败时,它给了我一条错误消息,说明它在其他表中被引用为外键。它列出了我认为的 3 个表,如果你按照它的线索,它会导致表dbo.AspNetUserClaims。aspNetUserClaims 设计师

aspNetUserClaims 设计师

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

aspNetUserClaims 唯一标识符

于 2020-10-23T21:13:01.020 回答
0

刚刚遇到这个问题,我并不清楚在保持迁移的同时如何解决它,所以我添加这个答案作为对@ChrFin 在他的评论中提到的内容的进一步澄清。

如果您通过迁移切换到IntId Guid,则必须在给定迁移中进行修改以创建UserManager.Create()不会失败的表:

//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));

有关需要更正的其他信息,以回答评论:

这些修改Up()采用自动生成的迁移文件的方法。AlterColumn("dbo.AspNetRoles", "Id", c => c.Int(nullable: false, identity: true));基本上,如果您遇到此问题,如果您在解决方案中搜索,您应该能够找到注释行(或等效行)。

迁移文件的Up()方法也将包含其他行/操作,但可以保持原样,只需要覆盖上述两个。

实际上,我有一段时间没有使用 ASP.NET MVC(切换到 Core),但据我回忆,迁移可以使用Updade-DatabasePackage Manager 命令行中的命令执行。

但是,当然,首先您必须回滚上次迁移(导致问题的未修改迁移)。据我所知,回滚到以前的迁移是使用Update-Database -TargetMigration:"migration_name"命令完成的,其中migration_name前面的名称是前面的,仍然很好的迁移。

于 2019-07-31T21:44:12.893 回答