实体框架代码的第一个唯一列


114

我正在使用Entity Framework 4.3和代码拳。

我有一堂课

public class User
{
   public int UserId{get;set;}
   public string UserName{get;set;}
}

如何在创建数据库表时告诉Entity Framework用户名必须唯一?如果可能的话,我宁愿使用数据注释而不是配置文件。

Answers:


257

在Entity Framework 6.1+中,您可以在模型中使用此属性:

[Index(IsUnique=true)]

您可以在以下命名空间中找到它:

using System.ComponentModel.DataAnnotations.Schema;

如果您的模型字段是字符串,请确保在SQL Server中未将其设置为nvarchar(MAX),否则您将在Entity Framework Code First上看到此错误:

表'dbo.y'中的列'x'的类型无效,无法用作索引中的键列。

原因是因为:

SQL Server保留所有索引键列的最大总大小的900字节限制。”

(摘自:http : //msdn.microsoft.com/zh-cn/library/ms191241.aspx

您可以通过在模型上设置最大字符串长度来解决此问题:

[StringLength(450)]

现在,您的模型在EF CF 6.1+中将如下所示:

public class User
{
   public int UserId{get;set;}
   [StringLength(450)]
   [Index(IsUnique=true)]
   public string UserName{get;set;}
}

更新:

如果您使用Fluent:

  public class UserMap : EntityTypeConfiguration<User>
  {
    public UserMap()
    {
      // ....
      Property(x => x.Name).IsRequired().HasMaxLength(450).HasColumnAnnotation("Index", new IndexAnnotation(new[] { new IndexAttribute("Index") { IsUnique = true } }));
    }
  }

并在您的modelBuilder中使用:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  // ...
  modelBuilder.Configurations.Add(new UserMap());
  // ...
}

更新2

有关EntityFrameworkCore的信息,请参阅以下主题:https : //github.com/aspnet/EntityFrameworkCore/issues/1698

更新3

有关EF6.2的信息,请参见:https : //github.com/aspnet/EntityFramework6/issues/274

更新4

具有EF Core的ASP.NET Core Mvc 2.2:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Unique { get; set; }

23
感谢您回复此人的旧帖子以及一些相关的当前信息!
Jim Yarbro 2014年

3
为什么是索引,为什么不只是约束?
约翰·亨克尔

2
要回答索引与"There are no significant differences between creating a UNIQUE constraint and creating a unique index that is independent of a constraint. Data validation occurs in the same manner, and the query optimizer does not differentiate between a unique index created by a constraint or manually created. However, creating a UNIQUE constraint on the column makes the objective of the index clear."
约束

3
注意; 在Entity Framework Core 1.0.0-preview2-final中,数据注释方法不可用-docs.efproject.net/en/latest/modeling/…–
Edward Comeau,

26

EF除键外不支持唯一列。如果使用的是EF迁移,则可以强制EF在UserName列上创建唯一索引(在迁移代码中,不通过任何注释),但是唯一性仅在数据库中强制执行。如果尝试保存重复值,则必须捕获数据库触发的异常(违反约束)。


1
那正是我想要的!我想知道是否有可能使用迁移来添加此类约束。
亚历克斯·乔根森

@Ladislav Mrnka:也可以通过Seed方法实现吗?
Raheel Khan 2013年

2
愿意提供一个例子吗?谢谢!
Zero3,2013年

10

从代码中可以明显看出您正在使用POCO。不需要另一个密钥:您可以按照juFo的建议添加索引。
如果使用Fluent API而不是归属UserName属性,则列注释应如下所示:

this.Property(p => p.UserName)
    .HasColumnAnnotation("Index", new IndexAnnotation(new[] { 
        new IndexAttribute("Index") { IsUnique = true } 
    }
));

这将创建以下SQL脚本:

CREATE UNIQUE NONCLUSTERED INDEX [Index] ON [dbo].[Users]
(
    [UserName] ASC
)
WITH (
    PAD_INDEX = OFF, 
    STATISTICS_NORECOMPUTE = OFF, 
    SORT_IN_TEMPDB = OFF, 
    IGNORE_DUP_KEY = OFF, 
    DROP_EXISTING = OFF, 
    ONLINE = OFF, 
    ALLOW_ROW_LOCKS = ON, 
    ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]

如果您尝试插入多个具有相同UserName的Users,则会收到DbUpdateException并显示以下消息:

Cannot insert duplicate key row in object 'dbo.Users' with unique index 'Index'. 
The duplicate key value is (...).
The statement has been terminated.

同样,列注释在6.1版之前的Entity Framework中不可用。


如何使用配置创建具有多列的索引?
FindOutIslamNow

一个在用户名上,另一个是什么?
亚历山大·克里斯托夫

5

请注意,在Entity Framework 6.1(当前为Beta)中,将支持IndexAttribute注释索引属性,这将自动在您的Code First迁移中产生(唯一)索引。



-13

EF4.3解决方案

唯一的用户名

在列上添加数据注释为:

 [Index(IsUnique = true)]
 [MaxLength(255)] // for code-first implementations
 public string UserName{get;set;}

唯一ID ,我在栏上添加了修饰[Key]并完成了操作。与此处描述的解决方案相同: https //msdn.microsoft.com/en-gb/data/jj591583.aspx

IE浏览器:

[Key]
public int UserId{get;set;}

替代答案

使用数据注释

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("UserId")]

使用映射

  mb.Entity<User>()
            .HasKey(i => i.UserId);
        mb.User<User>()
          .Property(i => i.UserId)
          .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
          .HasColumnName("UserId");

25
请谨慎使用此解决方案。将Key属性添加到UserName属性将导致该UserName属性成为数据库中的主键。仅该UserId属性应带有Key属性标记。此解决方案将在编程方面为您提供“正确”的行为,同时为您提供错误的数据库设计。
亚历克斯·乔根森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.