【问题标题】:How to work with field of inherited classes in Entity Framework如何在实体框架中使用继承类的字段
【发布时间】:2016-01-03 01:17:22
【问题描述】:

假设,我有数据表示的主类,而这个类有配置字段。该字段必须能够回答一些与主类相关的问题(假设这是一个问题 - 'IsMainClassReadyToUse')。但是这个类的内部结构可能不同。

正因为如此,我想创建 abstract class Configurator 并根据情况使用实现其功能的各种 Configuratos

所以,我有以下代码:

public class SimpleConfigurator : Configurator
{
    public int FieldA { get; set; }
    public override bool IsDataClassReadyToUse()
    {
        return ParentDataClass.FieldA == FieldA;
    }
}

public class ComplexConfigurator : Configurator
{
    public virtual List<int> FieldsB { get; set; }
    public override bool IsDataClassReadyToUse()
    {
        return ParentDataClass.FieldsB.All(x => FieldsB.Any(y => y == x));
    }
}

public abstract class Configurator
{
    public int ConfiguratorId { get; set; }
    public virtual DataClass ParentDataClass { get; set; }
    public abstract bool IsDataClassReadyToUse();
}

public class DataClass
{
    public int DataClassId { get; set; }
    public virtual Configurator Configurator { get; set; }
    public int FieldA { get; set; }
    public virtual List<int> FieldsB { get; set; }
}

public class DataDbContext : DbContext
{
    public DbSet<DataClass> DataClasses { get; set; }
}

但是当我尝试使用Configurator 类型为ComplexConfiguratorDataClass 实例时出现问题。

由于 LazyLoading 我需要从 ComplexConfigurator 加载 FieldsB,但 abstract class Configurator 不包含此类字段,我无法编写此类代码:

new DataDbContext().DataClasses
                   .Include(m => m.Configurator)
                   .Include(m => m.Configurator.FieldsB);

我试图禁用 LazyLoading,在DataDbContext 中添加这样的构造函数:

public DataDbContext()
{
    Configuration.LazyLoadingEnabled = false;
}

但是当我尝试访问 FieldsB 时,它仍然为空。

那么,我该如何使用 Entity Framework 来实现这样的架构呢?

或者我应该为这样的任务选择另一种架构?

【问题讨论】:

  • 您的DataDbContext 没有DbSetConfigurator,所以如果您能够访问Configurator 成员,我会感到惊讶,更不用说FieldsB 属性了。
  • @Gary 这个例子在SimpleConfigurator 下工作得很好,即使DataDbContext 中没有DbSet,我们也可以轻松访问它的实例。我想,实体框架本身可能会为Configurator 对象创建数据库。不是真的吗?
  • 你试过.Include("Configurator.FieldsB")。我目前没有时间设置本地数据库并对其进行测试,但理论上应该尝试加载有问题的属性;不过,我不能说生成的 SQL 会很高效。
  • @Richard 我收到A specified Include path is not valid 错误。
  • @NikitaSivukhin 将您课程中的 List&lt;int&gt; 更改为 ICollection&lt;int&gt;

标签: c# asp.net entity-framework


【解决方案1】:

我认为您应该尝试访问您的配置器,例如

((ComplexConfigurator)yourObject.Configurator).FieldsB

但我担心 EF 对 List&lt;int&gt; 属性的工作有误(当我尝试这样做时,有时我会失败),更好的方法是在您的配置器中创建类 Option 和字段 List&lt;Option&gt; Options 而不是用整数列出。

您还应该检查您的数据库方案(应该有一个表“配置器”,其中包含标识符字段以及所有 SimpleConfigurator 和 ComplexConfigurator 的字段)。也许您应该将DbSet&lt;Configurator&gt; 添加到您的 DbContext 定义中。

您可以阅读此article 以获取有关继承和 EF 的更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 2010-10-07
    • 1970-01-01
    相关资源
    最近更新 更多