Entity Framework 4.1 RC: code premier problème d’inheritance EntityTypeConfiguration

J’essaie d’utiliser une classe EntityTypeConfiguration commune pour configurer la clé primaire pour toutes mes entités, de sorte que chaque classe de configuration dérivée ne se répète pas. Toutes mes entités implémentent une interface commune IEntity (qui dit que chaque entité doit avoir une propriété Id de type int).

Ma classe de base de configuration ressemble à ceci:

public class EntityConfiguration : EntityTypeConfiguration where TEntity : class , IEntity { public EntityConfiguration() { HasKey( e => e.Id ); Property( e => e.Id ).HasDatabaseGeneratedOption( DatabaseGeneratedOption.Identity ); } } 

Chaque entité a alors sa propre classe de configuration spécifique qui étend celle-ci comme ceci:

 public class CustomerConfiguration : EntityConfiguration { public CustomerConfiguration() : base() { // Entity specific configuration here } } 

Cela comstack bien, mais le problème que je rencontre est qu’au moment de l’exécution, l’exception suivante est levée lorsque EF 4.1 RC essaie de créer le modèle:

System.InvalidOperationException non gérée Message = Le composant clé ‘Id’ n’est pas une propriété déclarée sur le type ‘Client’. Vérifiez qu’il n’a pas été explicitement exclu du modèle et qu’il s’agit d’une propriété primitive valide. Source = EntityFramework

Si je modifie la classe CustomerConfiguration pour qu’elle s’étende depuis EntityTypeConfiguration et répète la configuration de la clé primaire, cela fonctionne correctement, mais je perds la possibilité de partager une configuration commune (la motivation DRY est la motivation).

  • Est-ce que je fais quelque chose de mal ici?
  • Existe-t-il un autre moyen de partager une configuration commune entre entités?

Pour référence, voici les autres classes impliquées:

 public interface IEntity { int Id { get; set; } } public class Customer : IEntity { public virtual int Id { get; set; } public virtual ssortingng name { get; set; } } 

Merci!

Je ne pense pas que vous ayez besoin de traverser tout cela. EF 4.1 Code First utilise beaucoup de convention sur la configuration et, via celle-ci, la propriété Id d’une entité est configurée en tant que clé primaire. Donc, en implémentant l’interface IEntity sur vos entités, vous les configurez avec l’Id comme clé primaire.

Voici un lien vers le blog de l’équipe ADO.NET qui explique le fonctionnement de la convention de clé primaire – Conventions for Code First

Il semble que ces configurations présentent un problème d’interface. Cela fonctionne si vous changez IEntity en EntityBase :

 public class EntityBase { public virtual int Id { get; set; } } public class Customer : EntityBase { public virtual ssortingng Name { get; set; } } public class EntityConfiguration : EntityTypeConfiguration where TEntity : EntityBase { public EntityConfiguration() { HasKey(e => e.Id); Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); } } public class CustomerConfiguration : EntityConfiguration { public CustomerConfiguration() : base() { ... } } 

Vous pouvez simplement créer une méthode statique sur une classe et y transmettre l’entité. Par exemple:

 public class CustomerConfiguration : EntityConfiguration { public CustomerConfiguration() : base() { ... EntityConfiguration.Configure(this); } } public static class EntityConfiguration { public static void Configure(EntityTypeConfiguration entity) where TEntity : EntityBase { entity.HasKey(e => e.Id); entity.Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); } } 

J’ai un problème similaire avec EF5.0 lorsque j’ai une classe abstraite générique avec une propriété Id et une implémentation pour les membres abstraits et les propriétés auto-définies. ressembler d’abord à un code d’infrastructure ne cherche que les propriétés de la classe mappée. J’ai essayé d’utiliser un réflecteur – il semble que j’ai raison, mais je ne suis pas sûr de cela à 100%.

Et heureusement, nous avons trouvé une solution à cela:

  protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove(); modelBuilder.Entity() .Map(m => { **m.MapInheritedProperties();** }); } 

donc dans mon cas: pour mapper aussi les propriétés de la classe de base, je dois append une ligne de code m.MapInheritedProperties () …