ADO.Net Entity Framework : (八) 查詢時使用 ”IN” 的方式
當我們有這需求要查詢類似以下SQL語法時
select * from [user] where user_name in 'david','andy'
發現 Linq to Entity 並沒有提供類似 in 的語法,因此突發奇想,
改用另一個方式查詢如下
////範例一
using (TestEntities te = new TestEntities())
{
string[] names = new string[] { "david", "andy" };
var users = from a in te.User
where names.Contains(a.User_name)
select a;
GridView1.DataSource = users;
GridView1.DataBind();
}
結果發生錯誤 = =
LINQ to Entities 無法辨識方法 'Boolean Contains[String](System.Collections.Generic.IEnumerable`1[System.String], System.String)' 方法,而且這個方法無法轉譯成存放區運算式。
好吧,只好再嘗試其他方法,
改用 Query Builder Method
////範例二
using (TestEntities te = new TestEntities())
{
var users = te.User.Where("it.user_name in {'david','andy'}");
GridView1.DataSource = users;
GridView1.DataBind();
}
這次順利成功囉,
但是又不太甘心,因為少了intellsence 也無法在設計階段除錯
在介紹另一種方式,
我參考網路上找到的方法,建立了一個 ContainsExpression Method,
/// <summary>
/// 讓 EF 支援類似 SQL "IN" 的語法 ContainsExpression
/// </summary>
public static Expression<Func<TElement, bool>> ContainsExpression<TElement, TValue>(
Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values)
{
if (null == valueSelector)
{
throw new ArgumentNullException("valueSelector");
}
if (null == values)
{
throw new ArgumentNullException("values");
}
ParameterExpression p = valueSelector.Parameters.Single();
if (!values.Any())
{
return e => false;
}
var equals = values.Select(value => (Expression)Expression.Equal(valueSelector.Body, Expression.Constant(value, typeof(TValue))));
var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.Or(accumulate, equal));
return Expression.Lambda<Func<TElement, bool>>(body, p);
}
}
然後使用剛剛建立的 ContainsExpression Method 進行查詢,
////範例三
using (TestEntities te = new TestEntities())
{
string[] names = new string[] { "david", "andy" };
var users = te.User.Where(ContainsExpression<User, string>(a => a.User_name, names));
GridView1.DataSource = users;
GridView1.DataBind();
}
可以順利執行成功唷,
我們來看看實際執行時候的SQL語法長甚麼樣子
SELECT 1 AS [C1], [Extent1].[User_id] AS [User_id]
, [Extent1].[User_name] AS [User_name]
, [Extent1].[User_email] AS [User_email]
, [Extent1].[User_userdepartmentid] AS [User_userdepartmentid]
FROM [dbo].[User] AS [Extent1]
WHERE (N'david' = [Extent1].[User_name]) OR (N'andy' = [Extent1].[User_name])
這樣的好處是 會有intellsence,但是缺點是閱讀起來比較不直覺,加上執行時的SQL語法其實是用 OR OR OR 去組合起來的,
感覺效率上就沒有範例二 直接使用 Query Builder Method 來的好,
不過給大家參考一下囉
- 如果您覺得這篇文章有幫助,請您幫忙推薦一下或按上方的"讚"給予支持,非常感激
- 歡迎轉載,但請註明出處
- 文章內容多是自己找資料學習到的心得,如有不詳盡或錯誤的地方,請多多指教,謝謝