代码之家  ›  专栏  ›  技术社区  ›  xcelm

使用实体框架的唯一主键

  •  2
  • xcelm  · 技术社区  · 6 年前

    我对英孚不熟悉。假设我有一个这样的数据库表:

    ID    FirstName     LastName    DateOfBirth
    -------------------------------------------
    1     John          Smith       1.1.1990
    2     Mary          Wilson      5.1.1991
    

    现在,我使用ef将新实体插入到表中:

    dbcontext.Persons.Add(new Person
    {
        FirstName = "John",
        LastName = "Smith",
        DateOfBith = "1.1.1990"
    });
    dbcontext.SaveChanges();
    

    我需要代码引发异常,因为此行已存在于数据库中,但EF所做的是将ID列增加1并创建新记录:

    ID    FirstName     LastName    DateOfBirth
    --------------------------------------------
    1     John          Smith       1.1.1990
    2     Mary          Wilson      5.1.1991
    3     John          Smith       1.1.1990
    

    英孚能做到这一点吗?

    2 回复  |  直到 6 年前
        1
  •  4
  •   Salah Akbari    6 年前

    您已经定义了 ID 列作为 identity column 它被认为是您的主键,并且在您的表中插入新记录时会增加一个。这就是允许您插入重复实体的原因。您需要指定哪些列需要声明为pk,如果您使用的是代码优先方法,那么可以在模型中使用 Data Annotation ,如下所示:

    [Key]
    public string FirstName { get; set; }
    

    或者通过使用唯一约束:

    [Index("IX_UniqueConstraint", 1, IsUnique = true)]
    public string FirstName { get; set; }
    
    [Index("IX_UniqueConstraint", 2, IsUnique = true)]
    public string LastName { get; set; }
    
    [Index("IX_UniqueConstraint", 3, IsUnique = true)]
    public DateTime DateOfBirth { get; set; }
    

    您也可以使用 fluent API 为此目的:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Persons>().HasKey(c => new { c.FirstName, c.LastName, c.DateOfBirth });
    }
    

    或者,如果您使用的是DBFirst方法,那么您可以在数据库中声明它。

        2
  •  2
  •   Harambe    6 年前

    有了EF,你就需要这样做:

    [Index("IX_UniqueConstraint", 1, IsUnique = true)]
    public string FirstName { get; set; }
    
    [Index("IX_UniqueConstraint", 2, IsUnique = true)]
    public string LastName { get; set; }
    
    [Index("IX_UniqueConstraint", 3, IsUnique = true)]
    public DateTime DateOfBirth { get; set; }
    

    这将在3列中放置一个唯一的约束。