Linq到Sql-存储库模式-动态OrderBy
好的,我找到了,这将允许我这样做:Linq到Sql-存储库模式-动态OrderBy,linq,linq-to-sql,Linq,Linq To Sql,好的,我找到了,这将允许我这样做: public IList<Item> GetItems(string orderbyColumn) { return _repository.GetItems().OrderBy(orderByColumn).ToList(); } public IList GetItems(字符串orderbyColumn) { return _repository.GetItems().OrderBy(orderByColumn.ToList();
public IList<Item> GetItems(string orderbyColumn)
{
return _repository.GetItems().OrderBy(orderByColumn).ToList();
}
public IList GetItems(字符串orderbyColumn)
{
return _repository.GetItems().OrderBy(orderByColumn.ToList();
}
这是进行“动态”排序的最佳方式吗?我希望能够将列名作为字符串(以及排序方向)传递给我的服务,并使其以正确的方式排序。这当然是一种可行的动态排序方法。在到中提供了关于“强类型动态Linq排序”的另一个选项。我个人更喜欢Ch00k的方法,因为它涉及到一些编译时检查,并且很少涉及额外的代码。如果您已经决定它必须是一个字符串,那么您的选择就有点有限。动态LINQ库确实可以完成这项工作,或者,如果您不想知道它是如何工作的,那么看看这个函数,它在运行时从字符串构建一个
表达式
目前,代码只接受单个成员,并且有单独的升序/降序方法,但是从这个示例中,传递一个更复杂的字符串并拆分它应该相当简单;基本上是:
IQueryable<T> query = ...
string[] portions = orderBy.Split(' '); // split on space, arbitrarily
if(portions.Length == 0) throw new ArgumentException();
IOrderedQueryable<T> orderedQuery = query.OrderBy(portions[0]);
for(int i = 1 ; i < portions.Length ; i++) { // note we already did the zeroth
orderedQuery = orderedQuery.ThenBy(portions[i]);
}
return orderedQuery;
IQueryable查询=。。。
字符串[]部分=orderBy.Split(“”);//在空间上任意分割
如果(partments.Length==0)抛出新的ArgumentException();
IOrderedQueryable orderedQuery=query.OrderBy(部分[0]);
对于(inti=1;i
如果您刚刚完成动态排序,没有完整的动态Linq内容,您可以查看我不久前写的一篇文章:
编辑:我不再写博客了,所以这里是实际的扩展方法:
public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string sortExpression) where TEntity : class
{
if (string.IsNullOrEmpty(sortExpression))
return source; // nothing to sort on
var entityType = typeof(TEntity);
string ascSortMethodName = "OrderBy";
string descSortMethodName = "OrderByDescending";
string[] sortExpressionParts = sortExpression.Split(' ');
string sortProperty = sortExpressionParts[0];
string sortMethod = ascSortMethodName;
if (sortExpressionParts.Length > 1 && sortExpressionParts[1] == "DESC")
sortMethod = descSortMethodName;
var property = entityType.GetProperty(sortProperty);
var parameter = Expression.Parameter(entityType, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
MethodCallExpression resultExp = Expression.Call(
typeof(Queryable),
sortMethod,
new Type[] { entityType, property.PropertyType },
source.Expression,
Expression.Quote(orderByExp));
return source.Provider.CreateQuery<TEntity>(resultExp);
}
公共静态IQueryable OrderBy(此IQueryable源,字符串sortExpression),其中tenty:class
{
if(string.IsNullOrEmpty(sortExpression))
返回源;//没有要排序的内容
var entityType=类型(TEntity);
字符串ascSortMethodName=“OrderBy”;
字符串descSortMethodName=“OrderByDescending”;
字符串[]sortExpressionParts=sortExpression.Split(“”);
字符串sortProperty=sortExpressionParts[0];
字符串sortMethod=ascSortMethodName;
如果(sortExpressionParts.Length>1&&sortExpressionParts[1]=“描述”)
sortMethod=描述SortMethodName;
var property=entityType.GetProperty(sortProperty);
var参数=表达式参数(entityType,“p”);
var propertyAccess=Expression.MakeMemberAccess(参数,属性);
var orderByExp=Expression.Lambda(propertyAccess,参数);
MethodCallExpression resultExp=Expression.Call(
类型(可查询),
巫术,
新类型[]{entityType,property.PropertyType},
来源.表达式,
Expression.Quote(orderByExp));
返回source.Provider.CreateQuery(resultExp);
}
他的答案(Ch00k)也将是重构安全的,对属性进行重命名,代码将以字符串形式更新属性名称,这不会发生!它不必是字符串,但如何将排序列从控制器传递到存储库/服务?如果不是字符串,那么唯一明智的选择是lambda表达式,或者封装多个lambda表达式的对象。或者只使用现有的OrderBy/ThenBy.com,就好像博客条目是一个死链接@ray2k。。。你能更新吗?完成了。看起来新的链接也死了。你能在你的答案里把答案转贴在这里吗?