C# 在实体框架中创建动态linq排序和搜索order语句时
我试图构建一个函数,根据一些参数动态生成不同的查询。我对LINQ语法有点困惑,我不确定我是否做对了 字符串类型参数集是“搜索”(搜索文本框值)、“搜索字段”(搜索内容)、“限制开始”、“限制结束”,用于显示行数和开始位置。“订购依据”用于订购依据的字段。“order_sort”用于排序的方式 我以前在stackoverflow上发现过这个“getpropertyvalue”反射函数,我希望它能根据我自己的解释实现我的意图C# 在实体框架中创建动态linq排序和搜索order语句时,c#,asp.net,linq,entity-framework,C#,Asp.net,Linq,Entity Framework,我试图构建一个函数,根据一些参数动态生成不同的查询。我对LINQ语法有点困惑,我不确定我是否做对了 字符串类型参数集是“搜索”(搜索文本框值)、“搜索字段”(搜索内容)、“限制开始”、“限制结束”,用于显示行数和开始位置。“订购依据”用于订购依据的字段。“order_sort”用于排序的方式 我以前在stackoverflow上发现过这个“getpropertyvalue”反射函数,我希望它能根据我自己的解释实现我的意图 private static object GetPropertyVal
private static object GetPropertyValue(object obj, string property)
{
System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(property);
return propertyInfo.GetValue(obj, null);
}
我在“Orderby”行上遇到一个错误,VS2008以红色突出显示它,表示无法从用法推断参数类型。Orderby和
方法需要Func
类型的参数,并且您正在传递一个字符串。基本上,它要求您提供一个表达式,它可以用来标识要排序的属性。因为您必须从字符串开始,所以我的最佳想法是在OrderBy中使用反射
.OrderBy(x=>x.GetType().GetProperty(order\u by).GetValue(x,null).ToString())
正如您所看到的,这并不容易阅读,但应该可以做到这一点。您还可以在以下位置查看LINQ动态查询库:
希望这有帮助!:) 我过去就是这样处理的。注意是一个单列搜索和排序,这听起来像你要做的
var users = entities.UserTable;
// Setup the default order column.
Func<SweetEntity, string> orderFunc = u => u.Field1;
switch (searchfield)
{
case "Field1":
orderFunc = u => u.Field1;
users = users.Where(u => u.Field1.Contains(search));
break;
case "Field2":
orderFunc = u => u.Field2;
users = users.Where(u => u.Field2.Contains(search));
break;
}
// If you need to get the total count, do it here:
var totalUserCount = users.Count();
// Apply sorting:
if (order_sort == "ASC")
{
users = users.OrderBy(orderFunc);
}
else
{
users = users.OrderByDescending(orderFunc);
}
// Apply paging:
users = users.Skip(Convert.ToInt32(limit_begin)).Take(Convert.ToInt32(limit_end));
原始问题的主题可以通过表达式树和反射轻松实现
您可以查看将强类型Sort\Filter从字符串列名和值添加到EF6的工作示例
下面是链接中类的排序功能示例
public class GridRequestSort
{
public string PropName { get; set; }
public bool IsDescending { get; set; }
}
private static IQueryable<T> WrapSort<T>(
IQueryable<T> query,
GridRequestSort sort,
bool isFirst = false)
{
var propAccessExpr = GetPropAccesssLambdaExpr(typeof(T), sort.PropName);
var orderMethodName = "";
if (isFirst)
{
orderMethodName = sort.IsDescending ? "OrderByDescending" : "OrderBy";
}
else
{
orderMethodName = sort.IsDescending ? "ThenByDescending" : "ThenBy";
}
var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == orderMethodName && m.GetParameters().Length == 2);
var genericMethod = method.MakeGenericMethod(typeof(T), propAccessExpr.ReturnType);
var newQuery = (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, propAccessExpr });
return newQuery;
}
private static LambdaExpression GetPropAccesssLambdaExpr(Type type, string name)
{
var prop = type.GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
var param = Expression.Parameter(type);
var propAccess = Expression.Property(param, prop.Name);
var expr = Expression.Lambda(propAccess, param);
return expr;
}
公共类GridRequestSort
{
公共字符串PropName{get;set;}
公共bool isdescing{get;set;}
}
专用静态IQueryable WrapSort(
可查询的查询,
网格请求排序,
bool isFirst=false)
{
var propAccessExpr=GetPropAccesssLambdaExpr(typeof(T),sort.PropName);
var orderMethodName=“”;
如果(isFirst)
{
orderMethodName=sort.IsDescending?“OrderByDescending”:“OrderBy”;
}
其他的
{
orderMethodName=sort.IsDescending?“ThenBy Descending”:“ThenBy”;
}
var method=typeof(Queryable).GetMethods().FirstOrDefault(m=>m.Name==orderMethodName&&m.GetParameters().Length==2);
var genericMethod=method.MakeGenericMethod(typeof(T),propAccessExpr.ReturnType);
var newQuery=(IQueryable)genericMethod.Invoke(null,新对象[]{query,propAccessExpr});
返回newQuery;
}
私有静态LambdaExpression GetPropAccesssLambdaExpr(类型,字符串名称)
{
var prop=type.GetProperty(名称,BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
var param=表达式参数(类型);
var propAccess=Expression.Property(param,prop.Name);
var expr=Expression.Lambda(propAccess,param);
返回表达式;
}
但是如何在Where()子句中进行.Contains()搜索?是的,这不适用于OrderBy with Entities框架。它说灵到实体不识别ToString。这是完美的工作方式!还有我认为你不需要使用。ToString()很好的答案,我以前也看到过,它帮助了我。但现在我想去掉您的“switch…case”语句,并使其成为动态的。然后动态构造一个查询:
int myId;
if (int.TryParse(search, out myId))
{
users = users.Where(u => u.SomeIntegerField == myId);
}
public class GridRequestSort
{
public string PropName { get; set; }
public bool IsDescending { get; set; }
}
private static IQueryable<T> WrapSort<T>(
IQueryable<T> query,
GridRequestSort sort,
bool isFirst = false)
{
var propAccessExpr = GetPropAccesssLambdaExpr(typeof(T), sort.PropName);
var orderMethodName = "";
if (isFirst)
{
orderMethodName = sort.IsDescending ? "OrderByDescending" : "OrderBy";
}
else
{
orderMethodName = sort.IsDescending ? "ThenByDescending" : "ThenBy";
}
var method = typeof(Queryable).GetMethods().FirstOrDefault(m => m.Name == orderMethodName && m.GetParameters().Length == 2);
var genericMethod = method.MakeGenericMethod(typeof(T), propAccessExpr.ReturnType);
var newQuery = (IQueryable<T>)genericMethod.Invoke(null, new object[] { query, propAccessExpr });
return newQuery;
}
private static LambdaExpression GetPropAccesssLambdaExpr(Type type, string name)
{
var prop = type.GetProperty(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
var param = Expression.Parameter(type);
var propAccess = Expression.Property(param, prop.Name);
var expr = Expression.Lambda(propAccess, param);
return expr;
}