EF Code First实现了接口属性

我有以下型号。

interface IKeywordedEntity { IEntityCollection Keywords { get; } } class Foo : EntityBase, IKeywordedEntity { public virtual IEntityCollection Keywords { get { ... } } } class Bar : EntityBase, IKeywordedEntity { public virtual IEntityCollection Keywords { get { ... } } } 

我想编写一个扩展方法,在OnModelCreating为每个关键字自动处理关键字。

 public static void WithKeywords(this EntityTypeConfiguration entityTypeConfiguration) where TEntityType : EntityBase, IKeywordedEntity { entityTypeConfiguration.HasMany(e => e.Keywords).WithMany(); } 

所以我在OnModelCreating调用它。

 modelBuilder.Entity.WithKeywords(); modelBuilder.Entity.WithKeywords(); 

但是,我得到以下exception:

导航属性“关键字”不是“Foo”类型的声明属性。 validation它是否未从模型中明确排除,并且它是有效的导航属性。

我该怎么做才能让这种扩展方法有效?

在玩完这个之后我觉得你不会。 这是EF流畅的API中的限制或错误。 在您的扩展方法中,您不是映射Foo而是映射IKeywordEntity ,并且映射已损坏。 有两个问题–EF不喜欢接口,但即使你改变你的设计并使用抽象类而不是接口,它也适用于简单的属性,但它仍然不适用于导航属性。 至少这是我从自己的实验中得到的。

在阅读Ladislav的回答后,我决定手动编写表达式。

  public static void WithKeywords(this EntityTypeConfiguration entityTypeConfiguration) where TEntityType : EntityBase, IKeywordedEntity { var rootExpression = Expression.Parameter(typeof (TEntityType)); var expression = Expression.Property(rootExpression, "Keywords"); entityTypeConfiguration.HasMany(Expression.Lambda>>(expression, rootExpression)).WithMany(); } 

即使我不确定你的代码思路到底是什么(我得到你想要的东西) – 例如EntityBase在做什么,你是否在其中实现了关键词’
您需要确保以某种方式映射属性(并实际实现)
我认为你正在走向TPC模型 – 这意味着像这样……

 modelBuilder.Entity().Map(x => { x.MapInheritedProperties(); x.ToTable("Foo"); }) 

… MapInheritedProperties将为“具体”类型的“层次结构”排序。
你需要一个基类,抽象至少要实现属性,Code First可以选择它。
一个有点相关的问题……
entity framework4.1代码优先:获取具有特定基类的所有实体
简而言之,我认为你最好使用抽象类,但你仍然需要做一些工作 – 首先围绕代码进行概括并不是很容易引起许多警告。 你还需要直接获得你的inheritance模型,你需要的是什么。