Linq-to-Entities动态排序

ver*_*ror 18 c# linq entity-framework

这是我的查询,如何使用string作为orderby参数?

string sortColumn="Title";

var  items = (from ltem in ctxModel.Items
              where ltem.ItemID == vId
              orderby //something here
              select ltem).Skip(PageSize * PageIndex).Take(PageSize);
Run Code Online (Sandbox Code Playgroud)

更新:
我不能只是排序依据的结果集,因为我第一需要梳理,只有THEN页.

Fil*_*sen 13

我用这个助手:

public static class OrderExt
{
    private static IOrderedQueryable<T> Order<T>(this IQueryable<T> source, string propertyName, SortDirection descending, bool anotherLevel = false)
    {
        var param = Expression.Parameter(typeof(T), string.Empty);
        var property = Expression.PropertyOrField(param, propertyName);
        var sort = Expression.Lambda(property, param);

        var call = Expression.Call(
            typeof (Queryable),
            (!anotherLevel ? "OrderBy" : "ThenBy") +
            (descending == SortDirection.Descending ? "Descending" : string.Empty),
            new[] {typeof (T), property.Type},
            source.Expression,
            Expression.Quote(sort));

        return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(call);
    }
}
Run Code Online (Sandbox Code Playgroud)

调用助手,例如:

string sort = HttpContext.Current.Request.QueryString["sort"];
var products = _productRepository.OrderBy(sort, SortDirection.Ascending);
Run Code Online (Sandbox Code Playgroud)


Ste*_*ven 8

这是另一种选择,EntitySorter.允许动态LINQ对字符串执行的操作,但将操作包装在对象中,就像使用查询对象模式一样.它允许按字符串排序和类型安全结构.这里有些例子:

// Ways of defining an entity sorter
// 1. Using strings:
IEntitySorter<Person> sorter = EntitySorter<Person>
    .OrderBy("Address.City")
    .ThenByDescending("Id");

// 2. Defining a sorter with lambda's
IEntitySorter<Person> sorter = EntitySorter<Person>
    .OrderByDescending(p => p.Name)
    .ThenBy(p => p.Id)
    .ThenByDescending(p => p.Address.City);

// 3. Using a LINQ query
IEntitySorter<Person> sorter =
    from person in EntitySorter<Person>.AsQueryable()
    orderby person.Name descending, person.Address.City
    select person;

// And you can pass a sorter from your presentation layer
// to your business layer, and you business layer may look
// like this:
static Person[] GetAllPersons(IEntitySorter<Person> sorter)
{
    using (var db = ContextFactory.CreateContext())
    {
        IOrderedQueryable<Person> sortedList =
            sorter.Sort(db.Persons);

        return sortedList.ToArray();
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以在这里找到代码.


ker*_*vin 6

其他人建议使用动态链接或其他库. 就个人而言,我不会为这么小的任务带来库依赖.但你可以采取另外两条路径......

  • 使用对象调用语法并动态构建查询表达式树.例如...

http://blog.cincura.net/229310-sorting-in-iqueryable-using-string-as-column-name/

在此方案中考虑延迟执行很重要.您可以安全地构建返回IQueryable对象的查询,然后对该对象运行对象查询排序.只有在实际访问数据时,您的查询才会运行一次.

上面的博客文章是一个示例,说明如何使用Expression API构建和表达树,您可以将其用于OrderBy.这听起来真的很复杂.MSDN文章可能是更好的参考.请参见如何:使用表达式树在MSDN上构建动态查询.

要么

  • 使用简单路由,只需在整个查询的标题上使用开关即可.

例如.

ItemType items = default(ItemType);
switch(sortColumn)
{
     case "Title":
     {
           items = ctxModel.Items
                    .Where(i => i.ItemID == vId)
                    .OrderBy( i => i.Title);
     }
     break;
 }
Run Code Online (Sandbox Code Playgroud)

  • downvote触发手指抽搐,必须抵制.这就是IMO,动态的对立面.等等,它会来找我......哦是的,这是硬编码的X 2. ;-) (4认同)
  • @天空.你在说什么? (3认同)