EF Eager fetching derived class(EF Eager 获取派生类)
问题描述
我正在使用 EF6 并尝试获取对象的整个结构.问题是我正在使用继承.
I´m using EF6 and trying to eager fetch the whole structure of an object. The problem is that i´m using inheritance.
假设我有这个课程.
DbContext
DbSet<A> A { get; set; }
示例类
public class A
{
public string Id { get; set; }
public IList<Base> Bases { get; set; }
}
public abstract class Base
{
public int Id { get; set; }
public string Name { get; set; }
}
public abstract class Base1 : Base
{
public SomeClass SomeClass { get; set; }
}
public class Base2 : Base1
{
}
public class Base3 : Base1
{
public SomeOtherClass SomeOtherClass { get; set; }
}
我得到的错误是:
The Include path expression must refer to a navigation property defined on the type.
Use dotted paths for reference navigation properties and the Select operator for collection navigation properties.
为什么它不适用于以下内容?
Why doesn´t it work with the following ?
public IEnumerable<A> GetAll(string id)
{
return _ctx.A
.Include(x => x.Bases.OfType<Base1>().Select(y=>y.SomeClass))
.Where(x => x.Id.Equals(id)).ToList();
}
新示例
public IEnumerable<A> GetAll(string id)
{
var lists = _dbContext.A.Where(x => x.Id == id);
lists.SelectMany(a => a.Bases).OfType<Base1>().Include(e=>e.SomeClass).Load();
lists.SelectMany(b => b.Bases).OfType<Base3>().Include(e => e.SomeOtherClass).Load();
return lists;
}
添加了一个似乎可行的新示例.
Added a new example that seems to work.
推荐答案
简而言之,开箱即用是不可能的.
Shortly, it's not possible out of the box.
我可以建议的唯一解决方法是具体化主查询结果,然后使用与主查询相同的过滤器执行几个 OfType 查询以及必要的 Includes,然后依赖 EF 导航属性修复.
The only workaround I can suggest is to materialize the master query result, then execute several OfType queries with the necessary Includes using the same filter as the master query, and rely on EF navigation property fixup.
它需要 Base 类中的反向导航属性:
It requires an inverse navigation property in the Base class:
public abstract class Base
{
// ...
public A A { get; set; }
}
然后你可以使用这样的东西:
Then you can use something like this:
public IEnumerable<A> GetAll(string id)
{
var a = _ctx.A.Where(x => x.Id == id).ToList();
_ctx.Base.OfType<Base1>().Include(e => e.SomeClass).Where(e => e.A.Id == id).Load();
_ctx.Base.OfType<Base3>().Include(e => e.SomeOtherClass).Where(e => e.A.Id == id).Load();
return a;
}
同样的想法可以在不使用反向导航属性的情况下使用,但使用返回的基本 ID 作为过滤器:
The same idea can be used w/o inverse navigation property but with using the returned base Ids as filter:
public IEnumerable<A> GetAll(string id)
{
var a = _ctx.A.Include(e => e.Bases)
.Where(x => x.Id == id).ToList();
var baseIds = a.SelectMany(e => e.Bases.OfType<ModelA.Base1>().Select(b => b.Id));
db.Base.OfType<Base1>().Include(e => e.SomeClass)
.Where(e => baseIds.Contains(e.Id)).Load();
baseIds = a.SelectMany(e => e.Bases.OfType<Base3>().Select(b => b.Id));
db.Base.OfType<Base3>().Include(e => e.SomeOtherClass)
.Where(e => baseIds.Contains(e.Id)).Load();
return a;
}
这篇关于EF Eager 获取派生类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:EF Eager 获取派生类
基础教程推荐
- WPF 模态进度窗口 2022-01-01
- 如果有人提交恶意软件Nuget包怎么办? 2022-01-01
- 当值可以是对象或空数组时反序列化 JSON 2022-01-01
- .NET SerialPort DataReceived 事件未触发 2022-01-01
- Azure Functions:CosmosDBTrigger 未在 Visual Studio 中触发 2022-01-01
- 禁止输入少量字符,例如'<'、'&a 2022-01-01
- C# 从 List<List<int>> 中删除重 2022-01-01
- Moq It.Is<>不匹配 2022-01-01
- 我应该在后面的代码中直接使用 Linq To SQL 还是使 2022-01-01
- 如何使用 .Net 检查 Active Directory 服务器是否已启动并正在运行? 2022-01-01
