Maison >développement back-end >C++ >La commande dynamique LINQ peut-elle être appliquée à «ienumerable» ainsi qu'à «iQueryable»?

La commande dynamique LINQ peut-elle être appliquée à «ienumerable» ainsi qu'à «iQueryable»?

Patricia Arquette
Patricia Arquetteoriginal
2025-02-02 22:41:10391parcourir

Can Dynamic LINQ Ordering Be Applied to `IEnumerable` as Well as `IQueryable`?

Ordre de linq dynamique sur ienumerable & lt; t & gt; / IQueryable & lt; t & gt;

Dans dynamic linq, vous pouvez utiliser une chaîne de type SQL (par exemple, "OrderBy (" Name, Age DESC ")") pour commander les résultats. Cependant, les exemples disponibles jusqu'à présent ne fonctionnent qu'avec iQueryable & lt; t & gt;. Cela soulève la question: est-il possible d'étendre cette fonctionnalité à ienumerable & lt; t & gt ;?

s'étendant à iEnumerable & lt; t & gt;

pour y parvenir, vous pouvez créer un wrapper Méthodes qui utilisent Asqueryable. Cependant, le code ci-dessous sert de logique d'expression principale requis:

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 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;
}

Incorporer les fonctionnalités dynamiques

Pour les scénarios dynamiques Linq-Objects, vous pouvez tirer parti du système .Dynamic pour plus de flexibilité.

using Microsoft.CSharp.RuntimeBinder;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

/// <summary>
/// OrderBy for dynamic IEnumerable operations
/// </summary>
public static IOrderedEnumerable<dynamic> OrderBy(
    this IEnumerable<dynamic> source,
    string property)
{
    return Enumerable.OrderBy<dynamic, object>(
        source,
        AccessorCache.GetAccessor(property),
        Comparer<object>.Default);
}

/// <summary>
/// OrderByDescending for dynamic IEnumerable operations
/// </summary>
public static IOrderedEnumerable<dynamic> OrderByDescending(
    this IEnumerable<dynamic> source,
    string property)
{
    return Enumerable.OrderByDescending<dynamic, object>(
        source,
        AccessorCache.GetAccessor(property),
        Comparer<object>.Default);
}

/// <summary>
/// ThenBy for dynamic IEnumerable operations
/// </summary>
public static IOrderedEnumerable<dynamic> ThenBy(
    this IOrderedEnumerable<dynamic> source,
    string property)
{
    return Enumerable.ThenBy<dynamic, object>(
        source,
        AccessorCache.GetAccessor(property),
        Comparer<object>.Default);
}

/// <summary>
/// ThenByDescending for dynamic IEnumerable operations
/// </summary>
public static IOrderedEnumerable<dynamic> ThenByDescending(
    this IOrderedEnumerable<dynamic> source,
    string property)
{
    return Enumerable.ThenByDescending<dynamic, object>(
        source,
        AccessorCache.GetAccessor(property),
        Comparer<object>.Default);
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn