2011-12-12 45 views
2

我有一個Query子查詢中的NHibernate IQueryable.SingleOrDefault。使用功能謂語不執行

SpecialAttributesIEnumerable

q = from c in q 
    let x = c.SpecialAttributes.Where(a => a.Attribute.Id == id) 
           .Select(z => z.AttribValue).SingleOrDefault() 
    orderby Convert.ToDateTime(x) 
    select c; 

我需要馬上執行sql查詢。

但是在這種情況下,每個SingleOrDefault()將與主查詢分開執行。

如果提取結果的計數爲100 - SingleOrDefault()將執行100次。

它如何在一個查詢中,如FutureSingleOrDefault()

回答

2

假設你不會有相同的id屬性在你的特殊屬性的收集和你的「SpecialAttribute」類有父對象的引用,這可能工作:

q.SelectMany(x => x.SpecialAttributes) 
.Where(x => x.Attribute.Id == id) 
.OrderBy(x => Convert.ToDateTime(x.AttribValue)) 
.Select(x => x.Parent) 
.Distinct(); 

我不知道EF是否會將Convert.ToDateTime()解析爲適當的t-sql語句。如果沒有,你可以在內存中做到這一點(如果收集不是很大):

q.SelectMany(x => x.SpecialAttributes) 
.Where(x => x.Attribute.Id == id) 
.Select(x => new { Parent = x.Parent, Value = x.AttribVale}) 
.Distinct() 
.OrderBy(x => Convert.ToDateTime(x.Value)) 
.Select(x => x.Parent); 
+0

工作。但是有一個小問題。當'x.Parent'有一個空的SpecialAttributes時,它不會落入提取。我在表格中顯示'x.Parent',並且不能跳過沒有屬性的記錄。需要顯示所有記錄,包括帶有空的SpecialAttributes的'x.Parent' – Kronos

+0

解決方法是添加一個聯合(q.Where(x => x.SpecialAttributes == null))或類似的東西。它將用兩個查詢來解決,遠遠好於前面選擇的n + 1。無論如何,我會繼續思考一個更好的方法... – ivowiblo

+0

這是怎麼回事: q =從c在q 讓x =(從a在c.SpecialAttributes其中a.Attribute.Id == id選擇新{z .AttribValue})。FirstOrDefault() order by Convert.ToDateTime(x.AttribValue) select c; 兩件事:我將代碼更改爲100%linq樣式,遵循http://geekswithblogs.net/SudheersBlog/archive/2009/06/11/132758.aspx,並將SingleOrDefault()更改爲FirstOrDefault()。我認爲最後一部分可以做到這一點 – ivowiblo