Maison > développement back-end > C++ > Comment sélectionner dynamiquement des types anonymes avec plusieurs propriétés à l'aide des arbres d'expression LINQ ?

Comment sélectionner dynamiquement des types anonymes avec plusieurs propriétés à l'aide des arbres d'expression LINQ ?

Linda Hamilton
Libérer: 2025-01-22 19:01:11
original
933 Les gens l'ont consulté

How to Dynamically Select Anonymous Types with Multiple Properties Using LINQ Expression Trees?

Utilisez l'arborescence d'expressions LINQ pour sélectionner dynamiquement des types anonymes

Présentation

Les arbres d'expression LINQ fournissent un mécanisme puissant pour créer et modifier dynamiquement des requêtes. Un besoin courant consiste à sélectionner un type anonyme avec plusieurs propriétés. Bien que la sélection d'une seule propriété soit relativement simple, la définition de plusieurs propriétés dans un lambda sélectionné peut présenter des défis.

Solution utilisant l'émission réfléchie

Pour résoudre ce problème, nous pouvons utiliser l'émission réfléchissante et des classes auxiliaires pour générer dynamiquement des types anonymes. Le code suivant montre comment y parvenir :

Méthode SelectDynamic

<code class="language-csharp">public static IQueryable SelectDynamic(this IQueryable source, IEnumerable<string> fieldNames)
{
    // 创建属性名称和相应属性信息的字典
    Dictionary<string, PropertyInfo> sourceProperties = fieldNames.ToDictionary(name => name, name => source.ElementType.GetProperty(name));

    // 生成动态类型
    Type dynamicType = LinqRuntimeTypeBuilder.GetDynamicType(sourceProperties.Values);

    // 创建表达式树
    ParameterExpression sourceItem = Expression.Parameter(source.ElementType, "t");
    IEnumerable<MemberBinding> bindings = dynamicType.GetFields().Select(p => Expression.Bind(p, Expression.Property(sourceItem, sourceProperties[p.Name]))).OfType<MemberBinding>();

    Expression selector = Expression.Lambda(
        Expression.MemberInit(
            Expression.New(dynamicType.GetConstructor(Type.EmptyTypes)),
            bindings
        ),
        sourceItem
    );

    // 返回带有新select表达式的查询
    return source.Provider.CreateQuery(
        Expression.Call(
            typeof(Queryable),
            "Select",
            new Type[] { source.ElementType, dynamicType },
            Expression.Constant(source),
            selector
        )
    );
}</code>
Copier après la connexion

Classe LinqRuntimeTypeBuilder

<code class="language-csharp">public static class LinqRuntimeTypeBuilder
{
    // ...
    public static Type GetDynamicType(IEnumerable<PropertyInfo> fields)
    {
        // ...
        string className = GetTypeKey(fields); //  修改参数类型

        TypeBuilder typeBuilder = moduleBuilder.DefineType(className, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Serializable);

        foreach (var field in fields)                    
            typeBuilder.DefineField(field.Name, field.PropertyType, FieldAttributes.Public); // 使用field.Name 和 field.PropertyType

        return typeBuilder.CreateType();
    }
    // ...
}</code>
Copier après la connexion

Exemple d'utilisation

Pour sélectionner un type anonyme avec plusieurs propriétés, utilisez la syntaxe suivante :

<code class="language-csharp">var v = from c in Countries
        where c.City == "London"
        select new { c.Name, c.Population };</code>
Copier après la connexion

Vous pouvez désormais accéder aux propriétés de types anonymes comme n'importe quelle autre instance :

<code class="language-csharp">Console.WriteLine(v.Name);
Console.WriteLine(v.Population);</code>
Copier après la connexion

Remarque : L'extrait de code ci-dessus doit être complété par une implémentation complète de la classe LinqRuntimeTypeBuilder, y compris GetTypeKey et d'autres méthodes d'assistance qui peuvent être nécessaires. L'implémentation complète est complexe et nécessite la gestion de diverses exceptions et la vérification de type. Ceci est juste un exemple simplifié pour illustrer l’idée principale. Dans l'application réelle, l'amélioration et la gestion des erreurs doivent être effectuées en fonction des besoins spécifiques. De plus, l'utilisation directe de l'émission réfléchie pour créer des types dynamiques peut affecter les performances, et les avantages et les inconvénients doivent être pesés en fonction de la situation réelle.

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!

source:php.cn
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