我正在使用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