这是我的查询,如何使用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);
更新
我不能只是OrderBy结果集,因为我 FIRST 需要排序,只有 THEN 才能进行分页。
答案 0 :(得分: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);
}
}
调用助手,例如:
string sort = HttpContext.Current.Request.QueryString["sort"];
var products = _productRepository.OrderBy(sort, SortDirection.Ascending);
答案 1 :(得分:8)
这是另一种选择,EntitySorter。允许动态LINQ对字符串执行的操作,但将操作包装在对象中,就像使用Query Object pattern一样。它允许按字符串排序和类型安全构造。以下是一些例子:
// 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();
}
}
您可以找到代码here。
答案 2 :(得分:6)
其他人建议使用动态链接或其他库。 个人,我不会为这么小的任务带来库依赖。但是你可以采取另外两条路径......
请参阅http://blog.cincura.net/229310-sorting-in-iqueryable-using-string-as-column-name/
在这种情况下考虑Deferred Execution很重要。您可以安全地构建返回 IQueryable 对象的查询,然后对该对象运行对象查询排序。只有在实际访问数据时,您的查询才会运行一次。
以上博客文章是一个示例,说明如何使用Expression API构建和表达树,您可以将其用于 OrderBy 。这听起来真的很复杂。 MSDN文章可能是更好的参考。请参阅MSDN上的How to: Use Expression Trees to Build Dynamic Queries。
或
例如
ItemType items = default(ItemType);
switch(sortColumn)
{
case "Title":
{
items = ctxModel.Items
.Where(i => i.ItemID == vId)
.OrderBy( i => i.Title);
}
break;
}
答案 3 :(得分:4)
显然Dynamic Linq的其他暗示还不够明确。让我说清楚..
使用Dynamic Linq并不一定表明需要汇编依赖。
动态Linq包含在一个源文件中,如果我没有记错的话,它包含在C#样本中,每个人都应该至少在过去3年的某个时间看过,并且很容易被放入项目并命名为防止冲突,从而提供可在需要时使用的表达式构建服务。
我认为能够从一个合理的任意string
安全地构建一个表达式,它可以很容易地在动态构建,成为“动态”的最好例子。
考虑:
var query = northwind.Products
.Where("CategoryID = 3 AND UnitPrice > 3")
.OrderBy("SupplierID");
答案 4 :(得分:1)
该查询看起来像是在使用自定义数据绑定和/或ObjectDataSource,无论如何,有一种方法可以使用扩展方法来执行此操作,该方法采用排序表达式并动态地将一个OrderBy()调用(表达式)附加到linq查询。我记录了blog post一段时间后的情况,这恰好是this SO question的一部分。如果您需要更多,可以使用scottgu的{em> dynamic linq documented pretty well。
编辑:使用扩展方法会使它看起来像
string sortColumn="Title";
var items = (from ltem in ctxModel.Items
where ltem.ItemID == vId
select ltem).Skip(PageSize * PageIndex).Take(PageSize).OrderBy(sortColumn);