【问题标题】:Entity Framework 4.1 Code First: Get all Entities with a specific base classEntity Framework 4.1 Code First:获取具有特定基类的所有实体
【发布时间】:2011-04-28 13:04:34
【问题描述】:

我有一个 DbContext,其中设置了不同的 DbSet<T>s,所有类型都派生自同一个基类:

public class Foo : Entity { }
public class Bar : Entity { }

MyDbContext : DbContext
{
  public DbSet<Foo> Foos { get; set; }
  public DbSet<Bar> Bars { get; set; }
}

是否可以在一个查询中获取所有具有Entitybase 类的实体,例如:

DbContext.Set<Entity>();  // doesn't work

我尝试向 DbContext 引入显式 DbSet&lt;Entity&gt;,但这会导致数据库中的所有实体都使用一个大表。

附加问题:如果这能以某种方式工作,那么查询接口呢?

编辑:

我按照 Ladislav Mrnka 的link 上的说明进行了如下映射:

MyDbContext : DbContext
{
  public DbSet<Entity> Entities { get; set; }

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
    // Foo
    modelBuilder.Entity<Foo>().Map(x =>
    {
      x.MapInheritedProperties();
      x.ToTable("Foo");
    })
    .HasMany(x => x.Tags).WithMany();

    modelBuilder.Entity<Foo>()
        .Property(x => x.Id)
        .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

    // Bar
    // same thing for Bar and a bunch of other Entities

    base.OnModelCreating(modelBuilder);
  }
}

这会引发错误

属性“Id”不是类型“Foo”的声明属性。使用 Ignore 方法或 NotMappedAttribute 数据注释验证该属性是否已从模型中显式排除。确保它是一个有效的原始属性。

我还尝试将 Key 显式设置为 Id 属性:

modelBuilder.Entity<Foo>().Map(x => {...})
  .HasKey(x => x.Id)
  .HasMany(x => x.Tags).WithMany();

我错过了什么?

【问题讨论】:

  • 感谢您的链接。但似乎这是使用数据库优先方法的答案,而我正在寻找使用代码优先方法的解决方案。也许我在这里遗漏了什么,但我没有找到任何提示我的问题。

标签: inheritance mapping ef-code-first entity-framework-4.1 base-class


【解决方案1】:

您需要介绍TPC inheritance。之后DbContext.Set&lt;Entity&gt;() 将起作用,并且每个实体仍然有一个表。

【讨论】:

  • 谢谢,希望你能看到我的问题 ;-) 看起来像我正在寻找的东西,但还没有得到它的工作,与一堆错误作斗争......现在与 属性“Id”不是类型“Foo”的声明属性...。 id 在基类中声明,有什么想法吗?
  • 听起来你忘记使用MapInheritedPropeties 但当我没有看到你的映射时很难说。
  • 我刚刚用我尝试过的映射更新了我的问题。不要忘记MapInheritedProperties,我认为我完全按照说明进行操作...也许我对我的实体有一些额外的“特殊要求”... :-)
  • 因为这给了我原始问题的答案,所以我将其设置为我接受的答案。谢谢。
【解决方案2】:

在编辑部分解决您的问题:

错误消息表明您的基类Entity 中有Id 键属性。然后你需要在这个类而不是派生的Foo类上配置key属性:

modelBuilder.Entity<Entity>()
    .Property(x => x.Id)
    .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

【讨论】:

  • 有道理。现在我得到下一个错误:类型“Foo”不能按定义映射,因为它映射了使用实体拆分或其他形式继承的类型的继承属性。要么选择不同的继承映射策略以便不映射继承的属性,要么更改层次结构中的所有类型以映射继承的属性并且不使用拆分。 :-)
  • @Dave:不知道,我从未见过这个异常。这很可能与您的 foo 映射的这一部分有关:.HasMany(x =&gt; x.Tags)Tag 是什么?它也是从你的基类派生的吗?您是否也为这种类型定义了 TPC 映射?
  • 嗯,另一种解释:“它映射来自使用......另一种继承形式的类型的继承属性”所以,Foo 继承的“类型”是你的基类Entity。此类型使用“另一种继承形式”,这可能意味着Entity 派生类型Foo2 的另一个不映射继承属性。如果您没有为Foo2 配置映射,它默认使用TPH(“另一种继承形式”)而不是TPC。这可能意味着您需要为层次结构中的所有类型显式配置 TPC 以消除异常。
  • @Slauma:标签也派生自我的基类。我也怀疑这可能会导致错误,所以我尝试了同样的类型Tag,它不是从Entity 派生的。我为从基类派生的所有类型(包括Tag)定义了这些映射。 Entity实现了两个接口,可能是这个问题?
  • @Dave:我不认为接口有问题。我认为您需要在测试环境中逐步简化模型,并查看错误何时消失。如果没有看到您的完整模型,很难说可能出了什么问题。并且也许就这个问题提出一个新问题以引起更多关注。
猜你喜欢
  • 1970-01-01
  • 2012-08-24
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 2011-08-01
  • 1970-01-01
相关资源
最近更新 更多