EF 4.3.1 在 LinqToEntities 查询中包含继承的导航属性
本文关键字:继承 包含 导航 属性 查询 LinqToEntities EF | 更新日期: 2023-09-27 18:34:54
我正在尝试使用代码优先应用和流畅配置来设置EF 4.3.1的简单继承方案。
我创建了一个具有一对一导航属性的抽象基类型"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; }
}
当我尝试使用第一级导航属性取回数据时,它按预期工作:
... dataContext.AASet.Include("ChildB") ...
但是当我尝试包含继承类型的导航属性时,如下所示:
... dataContext.AASet.Include("ChildC") ...
我在运行时收到一个带有以下内部异常消息的实体命令编译异常:
指定表达式的结果类型与 必需类型。 表达式 ResultType 为 '瞬态参考[...A]' 但所需的类型是 '瞬态参考[...AA]'。参数名称:参数[0]
有没有人遇到过类似的问题?
我可能错过了一些东西,但我看不出这个样本有什么问题。
我该怎么做才能让我的模型按预期工作?
不,你不会错过任何东西。实际上,您遇到了一个旧的实体框架错误。您的第二个查询可以这样编写:
var result = dataContext.ASet.OfType<AA>().Include("ChildC").ToList();
(将数据库集AASet
替换为 ASet
时(。
对于继承类型上一对一映射子项的这种预先加载,本文适用: http://weblogs.asp.net/johnkatsiotis/archive/2010/04/28/huge-ef4-inheritance-bug.aspx
该错误很久以前就在这里报告过:https://connect.microsoft.com/VisualStudio/feedback/details/544639/ef4-继承-定义-使用-查询视图-不工作-正确与关联
该 bug 在 EF 4.3.1 中仍然存在。但是Microsoft在此线程中宣布该错误已在 .NET 4.5 ( = EF 5.0( 中修复。
如果关系是一对多而不是一对一,则代码将起作用。延迟或显式加载也可以(也具有一对一的关系(,我相信:
var result = dataContext.ASet.OfType<AA>().ToList();
foreach (var item in result)
dataContext.Entry(item).Reference(a => a.ChildC).Load();
但这将生成多个查询。如果您在使用多个查询时没有性能问题,我更喜欢最后一种解决方法 - 直到您可以迁移到 EF 5.0。