2009-05-14 32 views
3

閱讀之前downvoting或關閉:這個幾乎完全重複的previous question of mine是存在的唯一目的是改寫上一個問題到Linq-To-Sql範圍。上一個問題中包含的所有答案對Linq範圍均有效,但在Linq-To-SQL範圍內無效。如何重構多個類似的Linq-To-Sql查詢?

假設我有以下兩種LINQ到SQL查詢,我想重構:

var someValue1 = 0; 
var someValue2= 0; 
var query1 = db.TableAs.Where(a => a.TableBs.Count() > someValue1) 
       .Take(10); 
var query2 = db.TableAs.Where(a => a.TableBs.First().item1 == someValue2) 
       .Take(10); 

請注意,只有參數變化在哪裏。有什麼方法可以將查詢放在方法中並將Where參數作爲參數傳遞?

發佈在previous question中的所有解決方案都已經過嘗試,並且在嘗試枚舉結果時在運行時失敗。

引發的異常是:

回答

6

絕對「用於查詢操作‘去哪兒’不支持過載」。你會寫:

public IQueryable<A> First10(Expression<Func<A,bool>> predicate) 
{ 
    return db.TableAs.Where(predicate).Take(10); 
} 

(這是假設TableAIQueryable<A>

調用它:

var someValue1 = 0; 
var someValue2= 0; 
var query1 = First10(a => a.TableBs.Count() > someValue1); 
var query2 = First10(a => a.TableBs.First().item1 == someValue2); 

相信,將工作...

這與上一個問題的答案之間的區別基本上是這種方法需要Expression<Func<T,bool>>而不是僅僅是Func<T,bool>,所以它最終使用Queryable.Where而不是Enumerable.Where

+0

Strangr,我想這兩種情況下: 表達> c1 = t => true; Console.WriteLine(db.Table1.Where(c1).Count()); Func c2 = t => true; Console.WriteLine(db.Table1.Where(c2).Count()); 他們給了我相同的結果,沒有運行時錯誤。 – 2009-05-14 20:04:27

1

如果你真的想要重用,你可以嘗試寫你自己的操作符。例如。而不是重複寫入:

var query = 
Products 
    .Where(p => p.Description.Contains(description)) 
    .Where(p => p.Discontinued == discontinued); 

你可以寫簡單的方法:

public static IEnumerable<Product> ByName(this IEnumerable<Product> products, string description) 
{ 
    return products.Where(p => p.Description.Contains(description)); 
} 


public static IEnumerable<Product> AreDiscontinued(IEnumerable<Product> products, bool isDiscontinued) 
{ 
    return products.Where(p => p.Discontinued == discontinued); 
} 

,然後用它是這樣的:

var query = Products.ByName("widget").AreDiscontinued(false);