我正在使用EntityFramework核心,并试图加载仅存在于某种派生类型(全部在单个查询中)的导航属性。 可能最好用一个简单的例子来演示。EntityFramework核心:渴望加载派生类型的导航属性
假设你有一个像
class Transaction
{
public Product product { get; set; }
public DateTime date { get; set; }
}
abstract class Product
{
public string Name { get; set; }
}
class PhysicalProduct : Product
{
public Photo photo { get; set; }
}
class Service : Product
{
public Person provider { get; set; }
}
而且有些的DbContext
class MyContext : DbContext
{
public DbSet<Transaction> Transactions;
}
一些数据结构如何可以查询MyContext.Transactions返回的所有交易,并包括(贪婪加载)Transaction.product。照片(如果产品是PhysicalProduct)和Transaction.product.provider(如果产品是服务)?如上所述,试图用一个查询来实现这一点。
我已经试过如下:
// This is conceptually what I want to achieve.
// Not very surprisingly, this will throw an InvalidCastException
Transactions
.Include(x => ((PhysicalProduct)x.product).photo)
.Include(x => ((Service)x.product).provider)
.ToList();
// Based on http://stackoverflow.com/questions/7635152/entity-framework-eager-loading-of-subclass-related-objects
// Projection into an anonymous type, then transform back.
// doesn't work though, throws an InvalidOperationException, e.g.
// The property "photo" on entity type "Product" could not be found. Ensure that the property exists and has been included in the model.
// i.e. even though I wrapped this in a condition (x.product is PhysicalProduct), seems like EntityFramework still tries to execute or parse the statement thereafter even if the condition is not true.
var query = Transactions.Select(x => new
{
_transaction = x,
_physicalProductPhoto = (x.product is PhysicalProduct) ? ((PhysicalProduct)x.product).photo : null;
_serviceProvider = (x.product is Service) ? ((Service)x.product).provider : null;
})
.ToList() // Execute query. Exception will be thrown at this step.
.Select(x =>
{
var result = x._transaction;
if (x.product is PhysicalProduct)
((PhysicalProduct)x.product).photo = x._physicalProductPhoto;
else if(x.product is Service)
((Service)x.product).provider = x._serviceProvider;
return result;
})
.ToList();
任何人都可以想办法来实现这一目标? 谢谢!
谢谢伊万!不幸的是,这可能会使EF的大部分IAsyncEnumerable优势无效;加上它让我头痛,因为我无法执行并将密钥存入内存,这似乎与EFCore和GUID-Keys一起生成错误的SQL,所以需要像在您的示例中一样将IID保留为IQueryable(productIds ) - 尽管如此,多层次案例的一个障碍,例如包括本身属于派生类型的属性的派生类型的引用。无论如何,希望我能弄明白这一点;感谢您的意见,这非常有帮助! – Bogey