Heim > Backend-Entwicklung > C++ > Wie wähle ich anonyme Typen mit mehreren Eigenschaften mithilfe von LINQ-Ausdrucksbäumen dynamisch aus?

Wie wähle ich anonyme Typen mit mehreren Eigenschaften mithilfe von LINQ-Ausdrucksbäumen dynamisch aus?

Linda Hamilton
Freigeben: 2025-01-22 19:01:11
Original
932 Leute haben es durchsucht

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

Verwenden Sie den LINQ-Ausdrucksbaum, um anonyme Typen dynamisch auszuwählen

Einführung

LINQ-Ausdrucksbäume bieten einen leistungsstarken Mechanismus zum dynamischen Erstellen und Ändern von Abfragen. Ein häufiger Bedarf besteht darin, einen anonymen Typ mit mehreren Eigenschaften auszuwählen. Während die Auswahl einer einzelnen Eigenschaft relativ einfach ist, kann die Definition mehrerer Eigenschaften in einem ausgewählten Lambda eine Herausforderung darstellen.

Lösung mit reflektierter Emission

Um dieses Problem zu lösen, können wir reflektierende Emission und Hilfsklassen verwenden, um anonyme Typen dynamisch zu generieren. Der folgende Code zeigt, wie dies erreicht wird:

Dynamische Methode auswählen

<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>
Nach dem Login kopieren

LinqRuntimeTypeBuilder-Klasse

<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>
Nach dem Login kopieren

Beispielverwendung

Um einen anonymen Typ mit mehreren Eigenschaften auszuwählen, verwenden Sie die folgende Syntax:

<code class="language-csharp">var v = from c in Countries
        where c.City == "London"
        select new { c.Name, c.Population };</code>
Nach dem Login kopieren

Sie können jetzt wie bei jeder anderen Instanz auf Eigenschaften anonymer Typen zugreifen:

<code class="language-csharp">Console.WriteLine(v.Name);
Console.WriteLine(v.Population);</code>
Nach dem Login kopieren

Hinweis: Der obige Codeausschnitt muss durch eine vollständige Implementierung der LinqRuntimeTypeBuilder-Klasse ergänzt werden, einschließlich GetTypeKey und anderer Hilfsmethoden, die möglicherweise benötigt werden. Die vollständige Implementierung ist komplex und erfordert die Behandlung verschiedener Ausnahmen und Typprüfungen. Dies ist nur ein vereinfachtes Beispiel, um die Kernidee zu veranschaulichen. In der tatsächlichen Anwendung müssen Verbesserungen und Fehlerbehandlung entsprechend den spezifischen Anforderungen durchgeführt werden. Darüber hinaus kann die direkte Verwendung reflektierter Emission zum Erstellen dynamischer Typen Auswirkungen auf die Leistung haben, und die Vor- und Nachteile sollten basierend auf der tatsächlichen Situation abgewogen werden.

Das obige ist der detaillierte Inhalt vonWie wähle ich anonyme Typen mit mehreren Eigenschaften mithilfe von LINQ-Ausdrucksbäumen dynamisch aus?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage