当前位置: 首页 > 知识库问答 >
问题:

IEnumerable/IQueryable

万俟亦
2023-03-14

我在VS2008动态LINQ示例中找到了一个示例,它允许您使用类似SQL的字符串(例如,OrderBy(“Name,Age DESC”))进行排序。不幸的是,包含的方法仅适用于IQueryable


共有3个答案

於德馨
2023-03-14

只是偶然发现了这个问题。

使用上面Marc的ApplyOrder实现,我创建了一个扩展方法,可以处理类似SQL的字符串,如:

list.OrderBy("MyProperty DESC, MyOtherProperty ASC");

详情可在此找到:http://aonnull.blogspot.com/2010/08/dynamic-sql-like-linq-orderby-extension.html

糜帅
2023-03-14

太简单了,没有任何并发症:

  1. 使用系统添加。林克。动态的 在顶部
  2. 使用车辆=车辆。AsQueryable()。订购人(“制造ASC,年份描述”)。托利斯特()

编辑:为了节省一些时间,系统将。林克。动态Core(System.Linq.Dynamic不推荐使用)程序集不是框架的一部分,但可以从nuget:System安装。林克。动态果心

武峻熙
2023-03-14

只是偶然发现了这首老歌...

要在没有动态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括号之外再加上一个返回,我完全失去了我应该返回什么?因为你不是管理员,所以你不能返回任何东西