la combinazione di due campi deve essere univoca nel primo approccio al codice Entity Framework. come sarebbe?

Ho due contatti e gruppi di class

La combinazione di FirstName e LastName deve essere univoca e può aggiungere più indirizzi per un singolo contatto. Come posso farlo nel primo approccio al codice di struttura dell’ quadro?

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

Controllare i duplicati significa che devi andare al database per convalidare. In Entity Framework Code First, ciò significa utilizzare DbContext. Vedere Implementazione della convalida nel contesto con ValidateEntity per una grande spiegazione su come convalidare in Entity Framework.

Dovresti sovrascrivere il metodo ValidateEntity nella tua class di contesto:

  protected override DbEntityValidationResult ValidateEntity( DbEntityEntry entityEntry, IDictionary 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")); } 

Questa convalida viene triggersta quando c’è una chiamata a SaveChanges . Se ci sono errori, viene lanciata una DbEntityValidationException .

Maggiori informazioni sulla convalida della strutturazione qui

Per un approccio “belt and braces” aggiungo anche indici univoci al database sulle mie chiavi naturali – in una migrazione. Prevenendo così dati non validi a causa di inserimenti nel database che non vanno via 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"); } } 

Maggiori informazioni sugli indici qui

Nota aggiuntiva Da EF6.1 in poi è ansible indicare che un indice deve essere creato su un campo aggiungendo un attributo di dati:

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

Non c’è supporto magico per questo in Entity Framework. Dovrai farlo manualmente. Prima controlla se il contatto in un gruppo ha nomi univoci. Quindi verificare se esiste una combinazione FirstName/LastName nel database.

Tuttavia, questa non sarà mai una soluzione solida, perché ci sarà sempre una latenza tra il controllo e il commit finale nel database. Quindi, come ultima guardia, dovresti davvero aggiungere un indice di database univoco su FirstName/LastName .