使用Entity Framework实现自动递增主键

4

我有一张表格,想要向其中插入数据但不想指定UserID。我希望这个ID能够自动生成。

CREATE TABLE [dbo].[UserMaster] 
(
    [UserID]       INT           NOT NULL ,
    [UserName]     VARCHAR (50)  NULL,
    [UserPassword] VARCHAR (50)  NULL,
    [UserRoles]    VARCHAR (500) NULL,
    [UserEmailID]  VARCHAR (100) NULL,

    PRIMARY KEY CLUSTERED ([UserID] ASC)
);

这里我尝试使用C#插入行:

using (LessonesDBEntities context = new LessonesDBEntities())
{
    var u = new UserMaster//Make sure you have a table called UserMaster in DB
    {
        UserName = "test username",
        UserPassword = "test password",
        UserEmailID = "test email",
        UserRoles = "User"
    };

    context.UserMaster.Add(u);
    context.SaveChanges();
}

但我收到了异常:

主键约束'PK__tmp_ms_x__1788CCACDB8355D2'的违规。无法在对象'dbo.UserMaster'中插入重复键。重复键值为(0)。 已终止该语句。


使用IDENTITY属性 - Thom A
展示给我们你的上下文。你的主键没有自增标识。 - Georgi Georgiev
3个回答

5
在你的标识字段UserId上添加[DatabaseGenerated(DatabaseGeneratedOption.Identity)]属性。
public class UserMaster
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string UserPassword { get; set; }

    public string UserEmailID { get; set; }
    public string UserRoles { get; set; }
}

当你基于模型创建迁移和表格时,EF会创建带有自动递增的身份字段。

1
而且 SQL Server 表必须对列 UserId 使用 INT IDENTITY(1,1) - 仅此一项是不起作用的。 - marc_s
@marc_s ..而且我的答案还要求该表是由EF的Code First迁移创建的。 - Risto M
当你使用EF Code First时,迁移文件会有类似于Id = table.Column<int>(nullable: false).Annotation("SqlServer:Identity", "1, 1")的内容(在我第一次运行迁移时忘记了[DatabaseGenerated(DatabaseGeneratedOption.Identity)],结果不得不从头开始重新运行。希望只需添加.Annotation部分能让某人的生活更轻松。) - TomEberhard
而且...快照文件将包含以下内容: modelBuilder.Entity("Your_namespace_and_class", b => { b.Property<int>("UserId") .ValueGeneratedOnAdd() .HasColumnType("int") .HasAnnotation("SqlServer:IdentityIncrement", 1) .HasAnnotation("SqlServer:IdentitySeed", 1) .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); // 还有更多,所以重新创建迁移可能更安全 - TomEberhard

2
为了在数据库级别上实现自动递增,您应该在 DDL 中包含 IDENTITYUserID int identity(1,1) not null(1,1) 表示 UserID 将从 1 开始,并每次 INSERT 自增 1。

现在我得到了当IDENTITY_INSERT设置为OFF时,无法为表'UserMaster'中的标识列插入显式值。 - Plompy
@Plompy:你的C#模型类中的UserId列需要使用[DatabaseGenerated(DatabaseGeneratedOption.Identity)]注解进行修饰(参考@RistoM的其他答案),以使其正常工作。 - marc_s

1
Entity Framework并不知道你的整个数据库,它只知道你已经获取到上下文中的记录。因此,它无法确定给定表中使用的最大id。
你有三个选项:
1. 使用数据库的功能自动设置id,即自增的身份列。 2. 在数据库中编写一个函数返回最大id,并在EF中手动设置它。 3. 获取EF中的整个表格(完全加载),然后选择最大id。
我强烈反对选项2和3,建议使用选项1来使用数据库的自动增量功能。您应该通过EF插入它们,id为null,DB将设置id。您需要相应地标记该列。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接