我如何使用dynamicstring参数来执行OrderBy?
我想这样做:
var orderBy = "Nome, Cognome desc"; var timb = time.Timbratures.Include("Anagrafica_Dipendente") .Where(p => p.CodDipendente == 1); if(orderBy != "") timb = timb.OrderBy(orderBy);
是否有一个OrderBy
超载可用接受一个string参数?
绝对。 您可以使用Scott Guthrie博客上的LINQdynamic查询库。 CodePlex上还有更新版本。
它可以让你创buildOrderBy
子句, Where
子句,以及通过传递string参数来创build其他任何东西。 它非常适合为sorting/筛选网格创build通用代码等。
var result = data .Where(/* ... */) .Select(/* ... */) .OrderBy("Foo asc"); var query = DbContext.Data .Where(/* ... */) .Select(/* ... */) .OrderBy("Foo ascending");
如果您使用的是简单的LINQ到对象,而不想依赖于外部库,则不难实现您想要的function。
OrderBy()
子句接受从源元素获取sorting键的Func<TSource, TKey>
。 您可以在OrderBy()
子句外定义函数:
Func<Item, Object> orderByFunc = null;
您可以根据sorting标准将其分配给不同的值:
if (sortOrder == SortOrder.SortByName) orderByFunc = item => item.Name; else if (sortOrder == SortOrder.SortByRank) orderByFunc = item => item.Rank;
那么你可以sorting:
var sortedItems = items.OrderBy(orderByFunc);
此示例假定源types是具有属性Name
和Rank
Item
。
请注意,在这个例子中, TKey
是Object
,它不约束可以sorting的属性types。 如果函数返回一个值types(如Int32
),它将在sorting时被装箱,并且效率有点低。 如果您可以将TKey
约束为特定的值types,则可以解决此问题。
codeConcussion的另一个解决scheme( https://stackoverflow.com/a/7265394/2793768 )
var param = "Address"; var pi = typeof(Student).GetProperty(param); var orderByAddress = items.OrderBy(x => pi.GetValue(x, null));
在这里看这个博客。 它通过定义一个EntitySorter<T>
描述了一个这样做的方法。
它允许你传递一个IEntitySorter<T>
到你的服务方法中并像这样使用它:
public static Person[] GetAllPersons(IEntitySorter<Person> sorter) { using (var db = ContextFactory.CreateContext()) { IOrderedQueryable<Person> sortedList = sorter.Sort(db.Persons); return sortedList.ToArray(); } }
你可以像这样创build一个EntitiySorter
:
IEntitySorter<Person> sorter = EntitySorter<Person> .OrderBy(p => p.Name) .ThenByDescending(p => p.Id);
或者像这样:
var sorter = EntitySorter<Person> .OrderByDescending("Address.City") .ThenBy("Id");
您需要使用LINQ dynamic查询库来在运行时传递参数,
这将允许linq语句
string orderedBy = "Description"; var query = (from p in products orderby(orderedBy) select p);
最简单和最好的解决scheme:
mylist.OrderBy(s => s.GetType().GetProperty("PropertyName").GetValue(s));
你不需要这个外部库。 下面的代码适用于LINQ to SQL /实体。
/// <summary> /// Sorts the elements of a sequence according to a key and the sort order. /// </summary> /// <typeparam name="TSource">The type of the elements of <paramref name="query" />.</typeparam> /// <param name="query">A sequence of values to order.</param> /// <param name="key">Name of the property of <see cref="TSource"/> by which to sort the elements.</param> /// <param name="ascending">True for ascending order, false for descending order.</param> /// <returns>An <see cref="T:System.Linq.IOrderedQueryable`1" /> whose elements are sorted according to a key and sort order.</returns> public static IQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> query, string key, bool ascending = true) { if (string.IsNullOrWhiteSpace(key)) { return query; } var lambda = (dynamic)CreateExpression(typeof(TSource), key); return ascending ? Queryable.OrderBy(query, lambda) : Queryable.OrderByDescending(query, lambda); } private static LambdaExpression CreateExpression(Type type, string propertyName) { var param = Expression.Parameter(type, "x"); Expression body = param; foreach (var member in propertyName.Split('.')) { body = Expression.PropertyOrField(body, member); } return Expression.Lambda(body, param); }
(从https://stackoverflow.com/a/16208620/111438复制;CreateExpression
)
在上面的一个答案中:
最简单和最好的解决scheme:
mylist.OrderBy(s => s.GetType().GetProperty("PropertyName").GetValue(s));
有一个语法错误,必须添加,null
:
mylist.OrderBy(s => s.GetType().GetProperty("PropertyName").GetValue(s,null));