entity framework代码第一种方法中两个字段的组合必须是唯一的。 怎么会呢?

我有两个class级的联系人和组

FirstNameLastName组合必须是唯一的,并且可以为单个联系人添加多个地址。 我如何才能做到这一点在entity framework代码的第一种方法?

 public class Contacts { [Key] public int ContactID { get; set; } [ForeignKey("Group")] public int GroupID { get; set; } [Required] public string FirstName { get; set; } [Required] public string LastName { get; set; } [Required] public string Address { get; set; } [Required] public string Number { get; set; } [Required] [EmailAddress] public string EmailId { get; set; } [DataType(DataType.Date)] public DateTime CreateDate { get; set; } public DateTime? ModifiedDate { get; set; } public virtual Groups Group { get; set; } } public class Groups { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int GroupID { get; set; } [Required] public string GroupName { get; set; } [Required] public string GroupDiscription { get; set; } public DateTime CreateDate { get; set; } public DateTime ModifiedDate { get; set; } } 

检查重复意味着你必须去数据库validation。 在entity framework代码首先,这意味着使用DbContext。 请参阅使用ValidateEntity在上下文中实现validation,以获得有关如何在entity framework中进行validation的详细说明。

您应该重写上下文类中的ValidateEntity方法:

  protected override DbEntityValidationResult ValidateEntity( DbEntityEntry entityEntry, IDictionary<object, object> items) { //base validation for Data Annotations, IValidatableObject var result = base.ValidateEntity(entityEntry, items); //You can choose to bail out before custom validation //if (result.IsValid) // return result; CustomValidate(result); return result; } private void CustomValidate(DbEntityValidationResult result) { ValidateContacts(result); ValidateOrganisation(result); } private void ValidateContacts(DbEntityValidationResult result) { var c = result.Entry.Entity as Contact; if (c== null) return; if (Contacts.Any(a => a.FirstName == c.FirstName && a.LastName == c.LastName && a.ID != c.ID)) result.ValidationErrors.Add( new DbValidationError("Name", "Name already exists")); } private void ValidateOrganisation(DbEntityValidationResult result) { var organisation = result.Entry.Entity as Organisation; if (organisation == null) return; if (Organisations.Any(o => o.Name == organisation.Name && o.ID != organisation.ID)) result.ValidationErrors.Add( new DbValidationError("Name", "Name already exists")); } 

当调用SaveChanges时,会触发此validation。 如果有任何错误,则抛出DbEntityValidationException

更多关于这里的结构validation

对于“腰带和大括号”方法,我还在自然键上为数据库添加了唯一的索引 – 在迁移中。 从而防止无效的数据,因为插入到不通过entity framework的数据库:

 public partial class Adduniqueindexes : DbMigration { public override void Up() { //You have to use Sql if the column is nullable: Sql(@"CREATE UNIQUE INDEX IX_UPRN ON Properties(UPRN, OrganisationID) WHERE UPRN IS NOT NULL")); CreateIndex("dbo.Organisations", "Name", unique: true, name: "IX_NaturalKey"); CreateIndex("dbo.Contacts", new string[] { "FirstName", "LastName" }, unique: true, name: "IX_NaturalKey"); } public override void Down() { DropIndex("dbo.Properties", "IX_UPRN"); DropIndex("dbo.Organisations", "IX_NaturalKey"); DropIndex("dbo.Contacts", "IX_NaturalKey"); } } 

更多关于索引在这里

附加说明从EF6.1开始,可以通过添加数据属性来指示应该在字段上创build索引:

 [Index("IX_NaturalKey", IsUnique = true)] [Required] //If the field is nullable then you have to create the index in the migration //using sql, so I'd only expect IsUnique = true on a Required field [StringLength(256)] //indexes must be less than 900 bytes in Sql Server, //so nvarchar(max) will not do public string Name{ get; set; } 

entity framework中没有对此的神奇支持。 你必须手动执行此操作。 首先检查一批中的联系人是否有唯一的名字。 然后检查数据库中是否存在FirstName/LastName组合。

但是这绝不是一个可靠的解决scheme,因为检查和数据库的最终提交之间总会有延迟。 所以作为一个最终的守卫,你应该在FirstName/LastName上添加一个唯一的数据库索引。