[英]How to reuse where clauses in Linq To Sql queries
我有用戶搜索記錄類型的記錄。 他們在文本框中鍵入搜索詞,然后通過將多個字段與搜索詞匹配來搜索記錄。
我的查詢如下:
var results = from record in DataContext.Records
where
record.Field1.ToLower().Contains(term) ||
record.Field2.ToLower().Contains(term) ||
record.Field3.ToLower().Contains(term)
select record;
我有許多查詢都使用相同的過濾器,因此我想提取過濾,以便可以重復使用。 就像是:
var filter = new Func<Record, string, bool>(
(record, term) =>
record.Field1.ToLower().Contains(term) ||
record.Field2.ToLower().Contains(term) ||
record.Field3.ToLower().Contains(term)
);
var results = from record in DataContext.Records
where filter(record, term)
select record;
但是,它不起作用,因為:
方法'System.Object DynamicInvoke(System.Object [])'沒有支持的SQL轉換。
如何跨查詢重用where where條件?
您需要構建表達式而不是函數:
Expression<Func<Record, bool>> filter =
record => record.Field1.ToLower().Contains(term); // rest omitted
lambda表達式保持不變,但是你需要將它返回到Expression<Func<Record, bool>>
類型的變量中 - 這將使C#編譯器將其編譯為表達式而不是委托,允許它被傳遞到LINQ to SQL。
但是,您將無法將表達式變量與C#-syntax where子句一起使用:您需要使用Where擴展方法:
var results = DataContext.Records.Where(filter);
編輯添加:如果您希望能夠在不同的條件上創建過濾器,您只需要一個方法來從術語生成表達式:
private static Expression<Func<Record, bool>> Filter(string term)
{
return r => r.Field1.ToLower().Contains(term);
}
var results = DataContext.Records.Where(Filter(term));
如果您希望將filter
保留為目前的lambda,則可以這樣做,但泛型有點嵌套:
Func<string, Expression<Func<Record, bool>>> filter =
term => (r => r.Field1.ToLower().Contains(term));
var results = DataContext.Records.Where(filter(term));
無論如何,重要的是Where子句中的內容必須是Expression<Func<Record, bool>>
- 但是如上所示,您可以通過動態構建合適的表達式使表達式依賴於term
。 如果你在Where子句中詳細說明了過濾器,這正是LINQ to SQL所要做的。
使用CompiledQuery !
var filter = CompiledQuery.Compile(
(DatabaseDataContext dc, Record record, string term) =>
record.Field1.ToLower().Contains(term) ||
record.Field2.ToLower().Contains(term) ||
record.Field3.ToLower().Contains(term)
);
var results = from record in DataContext.Records
where filter(DataContext, record, term)
select record;
有關更多信息,請參見如何:存儲和重用查詢 。
除了其他人指出的Expression<Func<Record, bool>>
問題之外,我建議調查PredicateBuilder 。 這對於動態組合lambda表達式非常有用。
我想你需要把它變成Expression<Func<Record, bool>>
。 否則,它試圖將實際的C#方法調用轉換為SQL而不是它的描述。 這不能保證此版本能夠正常運行; 我不確定哪些字符串函數可以轉換為SQL。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.