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
Libérer: 2025-02-02 22:41:10
original
449 Les gens l'ont consulté

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;
}
Copier après la connexion

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);
}
Copier après la connexion

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 de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal