我正在使用 Entity Framework 4.3 并使用 Code Fist。
我有一堂课
public class User
{
public int UserId{get;set;}
public string UserName{get;set;}
}
创建数据库表时,如何告诉 Entity Framework UserName 必须是唯一的?如果可能的话,我更喜欢使用数据注释而不是配置文件。
我正在使用 Entity Framework 4.3 并使用 Code Fist。
我有一堂课
public class User
{
public int UserId{get;set;}
public string UserName{get;set;}
}
创建数据库表时,如何告诉 Entity Framework UserName 必须是唯一的?如果可能的话,我更喜欢使用数据注释而不是配置文件。
在 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; }
EF 不支持键以外的唯一列。如果您使用 EF 迁移,您可以强制 EF 在UserName
列上创建唯一索引(在迁移代码中,而不是通过任何注释),但唯一性将仅在数据库中强制执行。如果您尝试保存重复值,您将不得不捕获由数据库触发的异常(违反约束)。
从您的代码中可以明显看出您使用的是 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 版之前的实体框架中不可用。
在使用 FluentAPI 的 EF 6.2 中,您可以使用HasIndex()
modelBuilder.Entity<User>().HasIndex(u => u.UserName).IsUnique();
请注意,在 Entity Framework 6.1(当前处于测试阶段)中,将支持 IndexAttribute 来注释索引属性,这将自动在您的 Code First 迁移中生成(唯一)索引。
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");