擴(kuò)展 Entity Framework支持復(fù)雜的過濾條件(多個(gè)關(guān)鍵字模糊匹配)
問題描述
根據(jù)需求,我們需要編寫如下的SQL語句來查詢產(chǎn)品
select * from dbo.Product
where
(ProductName like 'Product1%' or
ProductName like 'Product2%')
如何將以上的SQL語句轉(zhuǎn)換成EF的寫法呢?
方案一
可以使用Union,將以上SQL語句轉(zhuǎn)換成以下的形式:
select * from dbo.Product
where
ProductName like 'Product1%'
UNION
select * from DocutapCMS.dbo.Product
where
ProductName like 'Product2%'
然后將上路SQL換成Linq To EF就非常簡單了,再此就不貼出來了。但每個(gè)條件都要寫一個(gè)Query,工作量大。如果條件太多,生成的SQL語句也非常大,并且寫起來很費(fèi)力。
方案二
我們從Linq To EF的Contains功能得到啟發(fā),Linq To EF 會將Contains轉(zhuǎn)換成IN表達(dá)式。
那么我們可不可以直接寫Expression,將條件轉(zhuǎn)換成上述SQL語句呢?答案是肯定的。以下就是實(shí)現(xiàn)上述方案的具體Linq To EF擴(kuò)展。
public static Expression<Func<TElement, bool>> BuildContainsExpression<TElement, TValue>(Expression<Func<TElement, TValue>> valueSelector,
IEnumerable<TValue> values)
{
var startsWithMethod = typeof (string).GetMethod("StartsWith", new[] { typeof(string) });
var startWiths = values.Select(value => (Expression)Expression.Call(valueSelector.Body, startsWithMethod, Expression.Constant(value, typeof(TValue))));
var body = startWiths.Aggregate<Expression>(((accumulate, equal) => Expression.Or(accumulate, equal)));
var p = Expression.Parameter(typeof(TElement));
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
用法:
private static void QueryProducts(IQueryable<Product> query)
{
var productNames = new string[] {"P1", "P2"};
var query1 = from a in query.Where(BuildContainsExpression<Product, string>(d=>d.ProductName, productNames))
select a;
var items2 = query1.ToList();
}
private static void QueryProducts(IQueryable<Product> query)
{
var productNames = new string[] {"P1", "P2"};
var query1 = from a in query.Where(BuildContainsExpression<Product, string>(d=>d.ProductName, productNames))
select a;
var items2 = query1.ToList();
}
創(chuàng)建擴(kuò)展方法,讓調(diào)用變得簡單
public static IQueryable<TElement> WhereOrLike<TElement, TValue>(this IQueryable<TElement> query,
Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
{
return query.Where(BuildContainsExpression<TElement, TValue>(valueSelector, values));
}
private static void QueryProducts2(IQueryable<Product> query)
{
var productNames = new string[] {"P1", "P2"};
query.WhereOrLike(d=>d.ProductName, productNames).ToList();
}
通過SQL Profile 監(jiān)視生成的SQL語句
-- Region Parameters
DECLARE @p0 NVarChar(3) = 'P1%'
DECLARE @p1 NVarChar(3) = 'P2%'
-- EndRegion
SELECT [t0].[Id], [t0].[ProductName]
FROM [Product] AS [t0]
WHERE ([t0].[ProductName] LIKE @p0) OR ([t0].[ProductName] LIKE @p1)
相關(guān)文章
MVC+EasyUI+三層新聞網(wǎng)站建立 tabs標(biāo)簽制作方法(六)
這篇文章主要為大家詳細(xì)介紹了MVC+EasyUI+三層新聞網(wǎng)站建立的第六篇,教大家如何制作tabs標(biāo)簽,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07.net indexOf(String.indexOf 方法)
字符串的IndexOf()方法搜索在該字符串上是否出現(xiàn)了作為參數(shù)傳遞的字符串,如果找到字符串,則返回字符的起始位置 (0表示第一個(gè)字符,1表示第二個(gè)字符依此類推)如果說沒有找到則返回 -12012-10-10jQuery+Asp.Net實(shí)現(xiàn)省市二級聯(lián)動功能的方法
這篇文章主要介紹了jQuery+Asp.Net實(shí)現(xiàn)省市二級聯(lián)動功能的方法,涉及asp.net數(shù)據(jù)庫讀取與字符串轉(zhuǎn)換相關(guān)操作技巧,需要的朋友可以參考下2017-05-05VS2010中呈現(xiàn)控件時(shí)出錯(cuò)的解決方法
如何解決“呈現(xiàn)控件時(shí)出錯(cuò)”的問題,這篇文章主要介紹了VS2010中出現(xiàn)"呈現(xiàn)控件時(shí)出錯(cuò)"問題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01ASP.NET MVC5網(wǎng)站開發(fā)管理列表、回復(fù)及刪除(十三)
這篇文章主要介紹了ASP.NET MVC5網(wǎng)站開發(fā)實(shí)現(xiàn)管理列表、回復(fù)及刪除,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-09-09Asp.net下用JQuery找出哪一個(gè)元素引起PostBack
在Asp.net webform中,如何找出哪一個(gè)按鈕觸發(fā)Button PostBack事件。2010-06-06asp.net利用反射實(shí)現(xiàn)給model類賦值的方法
這篇文章主要介紹了asp.net利用反射實(shí)現(xiàn)給model類賦值的方法,結(jié)合實(shí)例形式分析了asp.net使用反射給model類賦值的操作步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-03-03基于ASP.NET+EasyUI框架實(shí)現(xiàn)圖片上傳提交表單功能(js提交圖片)
這篇文章主要介紹了基于ASP.NET+EasyUI框架實(shí)現(xiàn)圖片上傳再提交表單(js提交圖片)的相關(guān)資料,需要的朋友可以參考下2016-06-06ASP.NET?MVC5網(wǎng)站開發(fā)之總體概述(一)
這篇文章主要為大家詳細(xì)介紹了ASP.NET?MVC5網(wǎng)站開發(fā)之總體概述,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08