我在VS2008动态LINQ示例中找到了一个示例,它允许您使用类似SQL的字符串(例如,OrderBy(“Name,Age DESC”))
进行排序。不幸的是,包含的方法仅适用于IQueryable
只是偶然发现了这个问题。
使用上面Marc的ApplyOrder实现,我创建了一个扩展方法,可以处理类似SQL的字符串,如:
list.OrderBy("MyProperty DESC, MyOtherProperty ASC");
详情可在此找到:http://aonnull.blogspot.com/2010/08/dynamic-sql-like-linq-orderby-extension.html
太简单了,没有任何并发症:
。林克。动态的
在顶部
使用车辆=车辆。AsQueryable()。订购人(“制造ASC,年份描述”)。托利斯特()
编辑:为了节省一些时间,系统将。林克。动态Core(System.Linq.Dynamic不推荐使用)程序集不是框架的一部分,但可以从nuget:System安装。林克。动态果心
只是偶然发现了这首老歌...
要在没有动态LINQ库的情况下实现这一点,您只需要以下代码。这涵盖了最常见的场景,包括嵌套属性。
要让它与IENumable一起工作
public static IOrderedQueryable<T> OrderBy<T>(
this IQueryable<T> source,
string property)
{
return ApplyOrder<T>(source, property, "OrderBy");
}
public static IOrderedQueryable<T> OrderByDescending<T>(
this IQueryable<T> source,
string property)
{
return ApplyOrder<T>(source, property, "OrderByDescending");
}
public static IOrderedQueryable<T> ThenBy<T>(
this IOrderedQueryable<T> source,
string property)
{
return ApplyOrder<T>(source, property, "ThenBy");
}
public static IOrderedQueryable<T> ThenByDescending<T>(
this IOrderedQueryable<T> source,
string property)
{
return ApplyOrder<T>(source, property, "ThenByDescending");
}
static IOrderedQueryable<T> ApplyOrder<T>(
IQueryable<T> source,
string property,
string methodName)
{
string[] props = property.Split('.');
Type type = typeof(T);
ParameterExpression arg = Expression.Parameter(type, "x");
Expression expr = arg;
foreach(string prop in props) {
// use reflection (not ComponentModel) to mirror LINQ
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);
object result = typeof(Queryable).GetMethods().Single(
method => method.Name == methodName
&& method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 2
&& method.GetParameters().Length == 2)
.MakeGenericMethod(typeof(T), type)
.Invoke(null, new object[] {source, lambda});
return (IOrderedQueryable<T>)result;
}
编辑:如果您想将其与
动态
混合使用,它会变得更有趣-不过请注意动态
仅适用于LINQ to对象(ORM等的表达式树不能真正表示动态
查询-成员表达式
不支持它)。但这里有一种方法可以使用LINQ to对象来实现这一点。请注意,Hashtable
的选择是由于良好的锁定语义:
using Microsoft.CSharp.RuntimeBinder;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Runtime.CompilerServices;
static class Program
{
private static class AccessorCache
{
private static readonly Hashtable accessors = new Hashtable();
private static readonly Hashtable callSites = new Hashtable();
private static CallSite<Func<CallSite, object, object>> GetCallSiteLocked(
string name)
{
var callSite = (CallSite<Func<CallSite, object, object>>)callSites[name];
if(callSite == null)
{
callSites[name] = callSite = CallSite<Func<CallSite, object, object>>
.Create(Binder.GetMember(
CSharpBinderFlags.None,
name,
typeof(AccessorCache),
new CSharpArgumentInfo[] {
CSharpArgumentInfo.Create(
CSharpArgumentInfoFlags.None,
null)
}));
}
return callSite;
}
internal static Func<dynamic,object> GetAccessor(string name)
{
Func<dynamic, object> accessor = (Func<dynamic, object>)accessors[name];
if (accessor == null)
{
lock (accessors )
{
accessor = (Func<dynamic, object>)accessors[name];
if (accessor == null)
{
if(name.IndexOf('.') >= 0) {
string[] props = name.Split('.');
CallSite<Func<CallSite, object, object>>[] arr
= Array.ConvertAll(props, GetCallSiteLocked);
accessor = target =>
{
object val = (object)target;
for (int i = 0; i < arr.Length; i++)
{
var cs = arr[i];
val = cs.Target(cs, val);
}
return val;
};
} else {
var callSite = GetCallSiteLocked(name);
accessor = target =>
{
return callSite.Target(callSite, (object)target);
};
}
accessors[name] = accessor;
}
}
}
return accessor;
}
}
public static IOrderedEnumerable<dynamic> OrderBy(
this IEnumerable<dynamic> source,
string property)
{
return Enumerable.OrderBy<dynamic, object>(
source,
AccessorCache.GetAccessor(property),
Comparer<object>.Default);
}
public static IOrderedEnumerable<dynamic> OrderByDescending(
this IEnumerable<dynamic> source,
string property)
{
return Enumerable.OrderByDescending<dynamic, object>(
source,
AccessorCache.GetAccessor(property),
Comparer<object>.Default);
}
public static IOrderedEnumerable<dynamic> ThenBy(
this IOrderedEnumerable<dynamic> source,
string property)
{
return Enumerable.ThenBy<dynamic, object>(
source,
AccessorCache.GetAccessor(property),
Comparer<object>.Default);
}
public static IOrderedEnumerable<dynamic> ThenByDescending(
this IOrderedEnumerable<dynamic> source,
string property)
{
return Enumerable.ThenByDescending<dynamic, object>(
source,
AccessorCache.GetAccessor(property),
Comparer<object>.Default);
}
static void Main()
{
dynamic a = new ExpandoObject(),
b = new ExpandoObject(),
c = new ExpandoObject();
a.X = "abc";
b.X = "ghi";
c.X = "def";
dynamic[] data = new[] {
new { Y = a },
new { Y = b },
new { Y = c }
};
var ordered = data.OrderByDescending("Y.X").ToArray();
foreach (var obj in ordered)
{
Console.WriteLine(obj.Y.X);
}
}
}
本文向大家介绍C#IEnumerable,包括了C#IEnumerable的使用技巧和注意事项,需要的朋友参考一下 示例 在其最基本的形式中,实现IEnumerable的对象表示一系列对象。可以使用c#foreach关键字迭代所讨论的对象。 在下面的示例中,该对象sequenceOfNumbers实现IEnumerable。它代表一系列整数。该foreach循环迭代通过每个反过来。
问题内容: MVC.net场景(和.net)是新手,但是当我想用数据填充“列表”时,似乎可以找到很多选择。就目前的情况而言,我想从项目的选择查询中填充一个列表,并将结果呈现为JSON以输出,因此请耐心等待…。 所以,我的viewmodel类是这样的: 然后,我想用查询输出填充它: 然后,我是否将输出循环到我的List中,以便随后可以在Json返回字符串中输出?当我使用 LIST VS IENUME
本文向大家介绍C#中的IEnumerable和IQueryable有什么区别?,包括了C#中的IEnumerable和IQueryable有什么区别?的使用技巧和注意事项,需要的朋友参考一下 IEnumerable存在于System.Collections命名空间中。 IQueryable存在于系统中。Linq命名空间。 IEnumerable和IQueryable都是正向收集。 IEnumera
我正在编写一个C#应用程序,通过一些监控邮箱,清除超过指定期限(例如6个月)的电子邮件。 以前我要获取这些项,然后在块中依次删除每个项。在寻找另一个问题的解决方案时,我无意中使用了。这需要,但在下面的代码中,返回。 如何转换或获取传递给DeleteItems的正确类型?
我编写了一个递归函数,该函数生成 所以如果我写 它应该屈服 但这并不像预期的那样奏效。(显示0)。 在正常的递归函数(返回int而不返回Ienumerable)中,它工作得很好。 问题: 我如何修复代码,使它产生预期的值? 注意:不,没有理由使用递归IEnumerables。这是我玩过递归收益后才想到的。
我有这个方法,我首先检查一个用户是否是admin,如果你是admin,你将从数据库中得到一个用户列表。但是VS告诉我,我必须在IF admin括号之外再加上一个返回,我完全失去了我应该返回什么?因为你不是管理员,所以你不能返回任何东西