我們有一條規則,不在服務層之外暴露IQueryable<T>
或IEnumerable<T>
,所以下游代碼無法修改前往數據庫的查詢。這意味着我們返回的類型就像IList或ICollection。在沒有返回IQueryable或IEnumerable的情況下返回單實體框架查詢中的父項和子項?
我想知道如何編寫linq查詢來獲取父項,並且它是孩子在單次訪問數據庫時沒有將子集合定義爲IQueryable
或IEnumerable
。
例如,假設從服務返回的類型ICollection<Parent>
其中Parent
的定義是這樣的:
public class Parent
{
public int ParentId { get; set; }
public string ParentName { get; set; }
public ICollection<Child> Children { get; set; }
}
如果我定義查詢,因爲這...
from p in dbContext.Parents
where p.Name.Contains("test")
select new Parent
{
Children =from c in dbContext.Children
where c.ParentId == p.ParentId
select c;
}
一點也沒有因爲IQueryable
沒有實現ICollection
。如果我將.ToList()
添加到父級和子級集合中,它會進行編譯,但現在它將爲每個父級單獨訪問數據庫以獲取它的子級。
當我寫這個問題時,我想到,也許答案是編寫Linq查詢來選擇匿名類型,然後將其映射到實際返回的類型。我們使用AutoMapper,它可以幫助映射。任何理由爲什麼這不起作用?在映射對象之前,我必須調用.ToList()
以確保映射時不會遇到同樣的問題嗎?
[Entity Framework遞歸地包含了來自包含集合中的每個實體的集合]的可能重複(http://stackoverflow.com/questions/24945115/entity-framework-recursively-include-collection-for-each-entity-from-包括公司) –
我可以理解,不想暴露'IQueryable',但我沒有看到不暴露'IEnumerable'的邏輯。首先,您的替代方案都會實施它。 –
另外,你的例子不能編譯(集合沒有名字,你的選擇器沒有指定任何屬性)。它看起來像你的要求可以滿足我只是返回'dbContext.Parents.Include(x => x.Children).Where(x => x.Name.Contains(「test」))',所以它可能不會真正說明你的觀點。 –