Comment résoudre ce problème: Le nombre de propriétés dans les rôles Dépendant et Principal dans une contrainte de relation doit être identique?

J’utilise Entity Framework 4.3.1 par rapport à une firebase database SQL Server 2012 et j’utilise l’approche POCO. Je reçois l’erreur suivante et je me demande si quelqu’un peut expliquer comment résoudre ce problème:

ModelValidationException

Une ou plusieurs erreurs de validation ont été détectées lors de la génération du modèle: \ tSystem.Data.Entity.Edm.EdmAssociationConstraint:: Le nombre de propriétés des rôles principal et des rôles dépendants doit être identique.

Il n’y a pas d’ InnerException disponible pour plus d’informations.

Je ne peux pas changer le schéma de la firebase database et c’est un peu étrange, mais le voici …

  • ** sont la clé primaire (notez que j’ai des clés primaires composites)
  • (FK) indique une clé étrangère

Voici les tables (si cela peut aider, je peux poster le code SQL pour les générer, mais je ne pense pas que ce sont les tables qui posent problème, car l’exception concerne la validation du modèle):

 One - **OneId int not null **TwoId int not null (FK) **ThreeId int not null (FK) Name nvarchar(50) not null Two - **TwoId int not null **ThreeId int not null (FK) Name nvarchar(50) not null Three - **ThreeId not null Name nvarchar(50) not null 

Voici les entités (notez que j’inclus les clés étrangères dans le modèle mais en dehors de cette jolie norme):

 public class Three { public int ThreeId { get; set; } public ssortingng Name { get; set; } public virtual ICollection Twos { get; private set; } public virtual ICollection Ones { get; private set; } public void AddOne(One one) { if (one == null) throw new ArgumentNullException("two"); if (Ones == null) Ones = new List(); if (!Ones.Contains(one)) Ones.Add(one); one.Three = this; } public void AddTwo(Two two) { if (two == null) throw new ArgumentNullException("two"); if (Twos == null) Twos = new List(); if (!Twos.Contains(two)) Twos.Add(two); two.Three = this; } } public class Two { public int TwoId { get; set; } public int ThreeId { get; set; } public ssortingng Name { get; set; } public virtual Three Three { get; set; } public virtual ICollection Ones { get; private set; } public void AddOne(One one) { if (one == null) throw new ArgumentNullException("two"); if (Ones == null) Ones = new List(); if (!Ones.Contains(one)) Ones.Add(one); one.Two = this; } } public class One { public int OneId { get; set; } public int TwoId { get; set; } public int ThreeId { get; set; } public virtual Two Two { get; set; } public virtual Three Three { get; set; } } 

Et voici le contexte de données:

 public class DbCtx : DbContext { public DbCtx(ssortingng connectionSsortingng) : base(connectionSsortingng) { Ones = Set(); Twos = Set(); Threes = Set(); } public DbSet Ones { get; private set; } public DbSet Twos { get; private set; } public DbSet Threes { get; private set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { var one = modelBuilder.Entity(); one.ToTable("One"); one.HasKey(d => new { d.OneId, d.TwoId, d.ThreeId }); one.Property(d => d.OneId) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); one.HasRequired(t => t.Two) .WithMany(s => s.Ones) .HasForeignKey(t => t.TwoId); one.HasRequired(t => t.Three) .WithMany(s => s.Ones) .HasForeignKey(t => t.ThreeId); var two = modelBuilder.Entity(); two.ToTable("Two"); two.HasKey(d => new { d.TwoId, d.ThreeId }); two.Property(p => p.TwoId) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); two.HasRequired(t => t.Three) .WithMany(s => s.Twos) .HasForeignKey(t => t.ThreeId); var three = modelBuilder.Entity(); three.ToTable("Three"); three.HasKey(s => s.ThreeId); three.Property(p => p.ThreeId) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); base.OnModelCreating(modelBuilder); } } 

Enfin, il s’agit d’un extrait de code qui provoque l’exception:

 using (var ctx = new DbCtx(@".....")) { Console.WriteLine(ctx.Twos.Count()); } 

La raison de l’erreur réside dans des relations mal configurées dans votre modèle. Ce n’est pas correct:

  one.HasRequired(t => t.Two) .WithMany(s => s.Ones) .HasForeignKey(t => t.TwoId); one.HasRequired(t => t.Three) .WithMany(s => s.Ones) .HasForeignKey(t => t.ThreeId); 

CA devrait etre:

  one.HasRequired(t => t.Two) .WithMany(s => s.Ones) .HasForeignKey(t => new { t.TwoId, t.ThreeId }); 

Parce que le FK de la personne à charge doit contenir toutes les colonnes de la PK principale. Vous devez également supprimer la propriété de navigation de Three en One .

Remarque pour EF5 +: .HasForeignKey est déconseillé pour EF 5: liste des méthodes disponibles ( https://msdn.microsoft.com/en-us/library/system.data.entity.modelconfiguration.configuration.manytomanyassociationmappingconfiguration_methods(v=vs. 103) .aspx ) – MapLeftKey – MapRightKey – ToTable

Si vous deviez avoir besoin de Plusieurs à plusieurs alors qu’un «Plusieurs» est destiné à une entité avec une clé composite, c’est:

 one.HasKey(t => new { t.TwoId, t.ThreeId }); one.HasRequired(t => t.Two) .WithMany(s => s.Ones) .Map(m=>m.MapLeftKey("OneId").MapRIghtKey(new ssortingng[]{"TwoId", "ThreeId"})) 

Cela peut aussi être causé par le premier code de la firebase database .

J’ai eu plusieurs points de vue que j’avais apportés qui n’avaient pas de champ clé évident selon les conventions Entity Framework. Le code généré place l’atsortingbut [Key] sur le mauvais champ. En fait, il ne pouvait détecter aucune unicité et a donc placé l’atsortingbut [Key] sur tous les champs.

J’ai pu supprimer tous les atsortingbuts de clé supplémentaires pour que l’erreur disparaisse.