简体   繁体   English

EF 4.3.1在LinqToEntities查询中包含继承的导航属性

[英]EF 4.3.1 Include inherited navigation properties in LinqToEntities query

I'm trying to setup a simple inheritance scenario with EF 4.3.1 using code first approch and fluent configuration. 我正在尝试使用代码优先和流畅的配置来设置EF 4.3.1的简单继承方案。

I've created an abstract base type 'A' with a one-to-one navigation property and an inherited class 'AA' also with a one-to-one navigation property has following : 我创建了一个具有一对一导航属性的抽象基类型'A',并且具有一对一导航属性的继承类'AA'具有以下内容:

public abstract class A
{
    public Guid ID { get; set; }
    public B ChildB { get; set; }
}

public class AA : A
{
    public C ChildC { get; set; }
}

public class B
{
    public Guid ID { get; set; }
    public A Parent { get; set; }
}

public class C
{
    public Guid ID { get; set; }
    public AA Parent { get; set; }
}

public class AConfiguration : EntityTypeConfiguration<A>
{
    public AConfiguration()
    {
        this.HasRequired(o => o.ChildB)
            .WithRequiredPrincipal(o => o.Parent);

        this.Map(o =>
        {
            o.ToTable("A");
        });
    }
}

public class AAConfiguration : EntityTypeConfiguration<AA>
{
    public AAConfiguration()
    {
        this.HasRequired(o => o.ChildC)
            .WithRequiredPrincipal(o => o.Parent);

        this.Map(o =>
        {
            o.ToTable("AA");
        });
    }
}

public class BConfiguration : EntityTypeConfiguration<B>
{
    public BConfiguration()
    {
        this.HasRequired(o => o.Parent)
            .WithRequiredDependent(o => o.ChildB);

        this.Map(o =>
        {
            o.ToTable("B");
        });
    }
}

public class CConfiguration : EntityTypeConfiguration<C>
{
    public CConfiguration()
    {
        this.HasRequired(o => o.Parent)
            .WithRequiredDependent(o => o.ChildC);

        this.Map(o =>
        {
            o.ToTable("C");
        });
    }
}

public class DataContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add<A>(new AConfiguration());
        modelBuilder.Configurations.Add<AA>(new AAConfiguration());
        modelBuilder.Configurations.Add<B>(new BConfiguration());
        modelBuilder.Configurations.Add<C>(new CConfiguration());
    }

    public DbSet<AA> AASet { get; set; }
    public DbSet<B> BSet { get; set; }
    public DbSet<C> CSet { get; set; }
}

When I try to get my data back with the first level of navigation property, it works as expected : 当我尝试使用第一级导航属性恢复数据时,它按预期工作:

... dataContext.AASet.Include("ChildB") ...

But when I try to include the navigation property of the inherited type like following : 但是当我尝试包含继承类型的导航属性时,如下所示:

... dataContext.AASet.Include("ChildC") ...

I get an EntityCommandCompilationException at runtime with the following inner exception message : 我在运行时遇到一个EntityCommandCompilationException,带有以下内部异常消息:

The ResultType of the specified expression is not compatible with the required type. 指定表达式的ResultType与所需类型不兼容。 The expression ResultType is 'Transient.reference[...A]' but the required type is 'Transient.reference[...AA]'. 表达式ResultType是'Transient.reference [... A]',但所需的类型是'Transient.reference [... AA]'。 Parameter name: arguments[0] 参数名称:arguments [0]

Has anybody encountered a similar issue ? 有没有人遇到过类似的问题?

I am probably missing something but I can't see what's wrong with this sample. 我可能遗漏了一些东西,但我看不出这个样本有什么问题。

What can I do to get my model works as expected ? 我该怎么做才能让我的模型按预期工作?

No, you don't miss anything. 不,你不会错过任何东西。 Actually you ran into an old Entity Framework bug. 实际上你遇到了一个旧的Entity Framework错误。 Your second query can be written like this: 您的第二个查询可以这样写:

var result = dataContext.ASet.OfType<AA>().Include("ChildC").ToList();

(when you replace your DbSet AASet by ASet ). (当您更换DbSet AASetASet )。

For this type of eager loading of one-to-one mapped children on inherited types this article applies: http://weblogs.asp.net/johnkatsiotis/archive/2010/04/28/huge-ef4-inheritance-bug.aspx 对于继承类型的这种类型的一对一映射子类的急切加载,本文适用: http//weblogs.asp.net/johnkatsiotis/archive/2010/04/28/huge-ef4-inheritance-bug.aspx

The bug has been reported long time ago here: https://connect.microsoft.com/VisualStudio/feedback/details/544639/ef4-inheritance-defined-using-queryview-doesnt-work-properly-with-association 很久以前在这里报告了这个bug: https//connect.microsoft.com/VisualStudio/feedback/details/544639/ef4-inheritance-defined-using-queryview-doesnt-work-properly-with-association

The bug still exists in EF 4.3.1. 该错误仍然存​​在于EF 4.3.1中。 But Microsoft has announced in this thread that the bug is fixed in .NET 4.5 ( = EF 5.0). 但是微软已经在这个帖子中宣布该错误已在.NET 4.5(= EF 5.0)中得到修复。

The code would work if the relationship is one-to-many instead of one-to-one. 如果关系是一对多而不是一对一,则代码将起作用。 Lazy or explicit loading would work as well (also with one-to-one relationship), I believe: 懒惰或显式加载也会起作用(也是一对一的关系),我相信:

var result = dataContext.ASet.OfType<AA>().ToList();
foreach (var item in result)
    dataContext.Entry(item).Reference(a => a.ChildC).Load();

But this will generate multiple queries. 但这会产生多个查询。 If you don't have performance problems with multiple queries I would prefer the last workaround - until you can migrate to EF 5.0. 如果您没有多个查询的性能问题,我宁愿使用上一个解决方法 - 直到您可以迁移到EF 5.0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM