Answers:
在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; }
"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."
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的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中不可用。
在使用FluentAPI的EF 6.2中,可以使用HasIndex()
modelBuilder.Entity<User>().HasIndex(u => u.UserName).IsUnique();
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
属性标记。此解决方案将在编程方面为您提供“正确”的行为,同时为您提供错误的数据库设计。