EF Code First实现了接口属性

时间:2012-03-25 20:59:14

标签: c# entity-framework ef-code-first

我有以下型号。

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

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

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

所以我在OnModelCreating中这样调用它。

modelBuilder.Entity<Foo>.WithKeywords();
modelBuilder.Entity<Bar>.WithKeywords();

但是,我得到以下例外:

  

导航属性“关键字”不是类型的声明属性   “富”。验证它是否未从模型中明确排除   并且它是一个有效的导航属性。

如何才能使此扩展方法有效?

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

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

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

        entityTypeConfiguration.HasMany(Expression.Lambda<Func<TEntityType, ICollection<Keyword>>>(expression, rootExpression)).WithMany();
    }

答案 2 :(得分:0)

即使我不确定你的代码思路究竟是什么(我得到你想要的东西) - 例如什么是EntityBase正在做什么,你有没有在其中实施的关键字
你需要确保你以某种方式(实际上已经实现)映射了属性 我认为你正在走向一个TPC模型 - 这意味着像这样......

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

... MapInheritedProperties将为“具体”类型排序“扁平化”层次结构 你需要一个基类,抽象至少要实现属性,Code First可以选择它 一个有点相关的问题......
Entity Framework 4.1 Code First: Get all Entities with a specific base class
简而言之,我认为你最好使用抽象类,但你仍然需要做一些工作 - 首先围绕代码进行概括并不是很容易引起许多警告。你还需要直接获得你的继承模型,你需要的是什么。