C# 在实体框架中创建动态linq排序和搜索order语句时

C# 在实体框架中创建动态linq排序和搜索order语句时,c#,asp.net,linq,entity-framework,C#,Asp.net,Linq,Entity Framework,我试图构建一个函数,根据一些参数动态生成不同的查询。我对LINQ语法有点困惑,我不确定我是否做对了 字符串类型参数集是“搜索”(搜索文本框值)、“搜索字段”(搜索内容)、“限制开始”、“限制结束”,用于显示行数和开始位置。“订购依据”用于订购依据的字段。“order_sort”用于排序的方式 我以前在stackoverflow上发现过这个“getpropertyvalue”反射函数,我希望它能根据我自己的解释实现我的意图 private static object GetPropertyVal

我试图构建一个函数,根据一些参数动态生成不同的查询。我对LINQ语法有点困惑,我不确定我是否做对了

字符串类型参数集是“搜索”(搜索文本框值)、“搜索字段”(搜索内容)、“限制开始”、“限制结束”,用于显示行数和开始位置。“订购依据”用于订购依据的字段。“order_sort”用于排序的方式

我以前在stackoverflow上发现过这个“getpropertyvalue”反射函数,我希望它能根据我自己的解释实现我的意图

 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;
        }