ChatGPT解决这个技术问题 Extra ChatGPT

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

我正在使用 Entity Framework 4.3 并使用 Code Fist。

我有一堂课

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

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


j
juFo

在 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/en-us/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;}
}

更新:

如果您使用流利:

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

并在您的模型构建器中使用:

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; }

感谢您用一些相关的当前信息回复这个家伙的旧帖子!
为什么是索引,为什么不只是一个约束?
要回答索引与约束问题...MSDN:"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." msdn.microsoft.com/en-us/library/ms187019.aspx
笔记;在 Entity Framework Core 1.0.0-preview2-final 中,数据注释方法不可用 - docs.efproject.net/en/latest/modeling/…
在 EntityFrameworkCore 中是这样完成的:[Index(propertyNames: nameof(UserName), IsUnique = true)] public class User { public int UserId{get;set;} [StringLength(450)] public string UserName{get;set;} }
L
Ladislav Mrnka

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


这正是我一直在寻找的!我想知道是否可以使用迁移添加此类约束。
@Ladislav Mrnka:这也可以通过 Seed 方法实现吗?
愿意提供一个例子吗?谢谢!
A
Anas Alweish

在使用 FluentAPI 的 EF 6.2 中,您可以使用 HasIndex()

modelBuilder.Entity<User>().HasIndex(u => u.UserName).IsUnique();

C
Community

从您的代码中可以明显看出您使用的是 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 的多个用户,您将收到带有以下消息的 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 版之前的实体框架中不可用。


使用配置创建具有多列的索引怎么样?
一个在 UserName 上,另一个是什么?
R
Robba

请注意,在 Entity Framework 6.1(当前处于测试阶段)中,将支持 IndexAttribute 来注释索引属性,这将自动在您的 Code First 迁移中生成(唯一)索引。


c
cpoDesign

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

小心这个解决方案。将 Key 属性添加到 UserName 属性将导致 UserName 属性成为数据库中的主键。只有 UserId 属性应使用 Key 属性进行标记。该解决方案将为您提供编程方面的“正确”行为,同时为您提供不正确的数据库设计。