【问题标题】:EF Code First implemented interface propertyEF Code First 实现的接口属性
【发布时间】:2012-03-25 20:59:13
【问题描述】:

我有以下型号。

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();

但是,我得到以下异常:

导航属性“关键字”不是类型上的声明属性 '福'。验证它没有被明确地从模型中排除 并且它是一个有效的导航属性。

我该怎么做才能让这个扩展方法起作用?

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      看了拉迪斯拉夫的回答后,我决定手动写表达式。

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

      【讨论】:

      【解决方案3】:

      即使我不确定您在这里的代码思路到底是什么(我明白您所追求的)-例如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
      简而言之,我认为你最好为此使用抽象类,但你仍然需要做一些工作 - 首先概括代码并不是那么容易引起许多警告的原因。此外,您还需要弄清楚您的继承模型,即您所追求的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-02
        • 1970-01-01
        • 1970-01-01
        • 2011-12-20
        • 1970-01-01
        • 1970-01-01
        • 2013-10-21
        • 1970-01-01
        相关资源
        最近更新 更多