2011-06-07 67 views
14

我有類,如:預先加載屬性包括

Person 
{ 
    Name 
    Address 
} 

Employee : Person 
{ 
    Compensation - object 
} 

Visitor : Person 
{ 

} 

如果我寫LINQ:

var persons = Context.Persons 
       .Include("Compensation"); 

我得到錯誤:

A specified Include path is not valid. The EntityType 'Person' does not declare a navigation property with the name 'Compensation'.

它的工作原理確定的,如果我這樣做:

var persons = Context.Persons 
       .OfType<Employee>() 
       .Include("Compensation"); 

但我想在同一查詢中獲得員工和訪問者。

看起來有對EF4 UserVoice的此功能的要求: http://data.uservoice.com/forums/72025-ado-net-entity-framework-ef-feature-suggestions/suggestions/1249289-include-property-of-derived-classes?ref=title

,但它並不像它會被很快完成任何時間。

這個問題的解決方法是什麼?

回答

7

你可以試試這樣說:

var persons = Context.Persons 
        .OfType<Employee>() 
        .Include("Compensation") 
        .Concat<Person>(Context.Persons.OfType<Visitor>()); 
+0

變化的concat行:.Concat (Context.Persons.OfType ());否則不編譯。運行時仍然會得到與原始問題相同的錯誤。 – 2011-06-07 10:14:13

+0

@Ladislav,在我的場景中,Person類型不是抽象的,有的實體只是'Person'既不''Employee'或'Visitor'。你的例子不會給我那些**人的**。試圖結合'Person'查詢導致OP報告的異常。任何解決方法將非常感激(在我的情況下,它不是'Person',它是'Transaction',但不管)。 – Shimmy 2012-02-28 09:14:22

+0

@Shimmy:以問題爲例提出一個單獨的問題,並引用這個問題。評論不太適合解決另一個(甚至類似的)問題。 – 2012-02-28 09:22:32

0

這可怕的工作:

var persons = context.Persons 
       .Concat(context.Employees 
        .Where(e => e.Compensation.Amount >= 0)) 
       .Concat(context.Visitors 
        .Where(v => v.SomeProperty == "AlwaysTrue")); 

我不知道爲什麼,但是當你對一個對象的屬性過濾器,該屬性的對象急切地加載。如果您不想過濾該屬性,請使用始終爲真的條件。

聲明:我不知道生成的查詢的效率如何。我檢查了生成的sql,當我在稍微複雜的場景中測試它時,它非常大。

+0

這很瘋狂......我試圖做這項工作,但我的導航屬性是一個集合。有關於此的任何想法?我嘗試過的所有東西仍然不加載收藏。 – julealgon 2014-08-15 21:22:08

2

下面是如何加載Persons,包括CompensationEmployees

通過Collection()爲一個集合屬性替換Reference()一個很好的例子。

IQueryable<Person> GetPersons() 
{ 
    var persons = Context.Persons; 
    foreach(var entry in persons.OfType<Employee>()) 
     Context.Entry(entry).Reference(e => e.Compensation).Load(); 
    return persons; 
} 

不確定它是否是有效的,但它的工作原理,其目的比連接更清晰。

在此基礎上SO answer

2
var employees = context.Persons.OfType<Employee>().Include(x => x.Compensation).ToArray(); 

var nonEmployees = context.Persons.Except(context.Persons.OfType<Employee>()).ToArray(); 

var people = employees.Concat(nonEmployees);