[英]LINQ to SQL lambda exp. OrderBy, Case When,Dynamic Where
[英]where can I find a good example of using linq & lambda expressions to generate dynamic where and orderby sql?
在哪里可以找到使用linq和lambda表達式生成動態sql的好例子? 例如,我需要一種方法來獲取這些參數
GoupOperator ('And' or 'OR')
A list of objects each with the following parameters:
SearchColumn.
SearchValue.
SearchOperator (equals, contains, does not equal ...)
另一種通過任何特定列升序或降序進行排序的方法
如果此問題之前已得到正確回答,我將很樂意將其刪除-我見過的以前的回答都沒有足夠全面,足以讓linq表達式新手能夠輕松插入到現有應用程序中-謝謝
我在代碼項目上找到了幾個linq擴展方法(由Ilya Builuk編寫的通用Where和OrderBy方法,它們使用列名,搜索值和搜索操作以及分組運算符)在此處顯示了如何使用asp.net mvc進行此操作。 這些方法構造了一個動態表達式樹-非常優雅的解決方案。 由於我開始使用傳統的asmx網絡服務,因此我在項目中使用了他的助手,並做了一些更改才能使其在這里運行-
這是兩種方法
public static class LinqExtensions
{
/// <summary>Orders the sequence by specific column and direction.</summary>
/// <param name="query">The query.</param>
/// <param name="sortColumn">The sort column.</param>
/// <param name="ascending">if set to true [ascending].</param>
public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string sortColumn, string direction)
{
string methodName = string.Format("OrderBy{0}",
direction.ToLower() == "asc" ? "" : "descending");
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = null;
foreach (var property in sortColumn.Split('.'))
memberAccess = MemberExpression.Property
(memberAccess ?? (parameter as Expression), property);
LambdaExpression orderByLambda = Expression.Lambda(memberAccess, parameter);
MethodCallExpression result = Expression.Call(
typeof(Queryable),
methodName,
new[] { query.ElementType, memberAccess.Type },
query.Expression,
Expression.Quote(orderByLambda));
return query.Provider.CreateQuery<T>(result);
}
public static IQueryable<T> Where<T>(this IQueryable<T> query,
string column, object value, WhereOperation operation)
{
if (string.IsNullOrEmpty(column))
return query;
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = null;
foreach (var property in column.Split('.'))
memberAccess = MemberExpression.Property
(memberAccess ?? (parameter as Expression), property);
//change param value type
//necessary to getting bool from string
ConstantExpression filter = Expression.Constant
(
Convert.ChangeType(value, memberAccess.Type)
);
//switch operation
Expression condition = null;
LambdaExpression lambda = null;
switch (operation)
{
//equal ==
case WhereOperation.Equal:
condition = Expression.Equal(memberAccess, filter);
lambda = Expression.Lambda(condition, parameter);
break;
//not equal !=
case WhereOperation.NotEqual:
condition = Expression.NotEqual(memberAccess, filter);
lambda = Expression.Lambda(condition, parameter);
break;
//string.Contains()
case WhereOperation.Contains:
condition = Expression.Call(memberAccess,
typeof(string).GetMethod("Contains"),
Expression.Constant(value));
lambda = Expression.Lambda(condition, parameter);
break;
}
MethodCallExpression result = Expression.Call(
typeof(Queryable), "Where",
new[] { query.ElementType },
query.Expression,
lambda);
return query.Provider.CreateQuery<T>(result);
}
}
下面是我使用這些方法的方式,返回對象只是一個自定義對象,它將數據提供給客戶端網格
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public JgGrid SearchGrid(int rows, int page, string sidx, string sord,string filters)
{
AdvWorksDataContext dc = new AdvWorksDataContext();
JavaScriptSerializer serializer = new JavaScriptSerializer();
filters f = serializer.Deserialize<filters>(filters);
var p = dc.vProductAndDescriptions.AsQueryable();
if (f.groupOp == "AND")
foreach (var rule in f.rules)
p = p.Where<vProductAndDescription>(
rule.field, rule.data,
(WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op)
);
else
{
//Or
var temp = (new List<vProductAndDescription>()).AsQueryable();
foreach (var rule in f.rules)
{
var t = p.Where<vProductAndDescription>(
rule.field, rule.data,
(WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op)
);
temp = temp.Concat<vProductAndDescription>(t);
}
p = temp;
}
p = p.OrderBy<vProductAndDescription>(sidx, sord);
return new JgGrid(page, p, rows);
}
}
對於我有許多需要動態查詢組合的列的情況,我使用動態Linq。 這是一個以.net 3.5為例編寫的庫,它說明了如何編寫對表達式樹進行操作的linq擴展。
它也可以用於根據從客戶端接收的字符串(例如列名,排序等)組成動態查詢。
這是斯科特·古思里(Scott Guthrie)發表的文章的鏈接, 網址為http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library .aspx
在本文中,您將找到示例庫的鏈接,該庫包含Dynamic Linq庫的源代碼。
在我看來,您正在嘗試構建linq提供程序...嘗試檢查有關如何實現自定義Linq to SQL提供程序的本教程系列: LINQ:構建IQueryable提供程序系列
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.