LINQ 표현식 트리를 사용하여 익명 유형을 동적으로 선택
소개
LINQ 식 트리는 쿼리를 동적으로 생성하고 수정하기 위한 강력한 메커니즘을 제공합니다. 일반적인 요구 사항은 여러 속성이 있는 익명 유형을 선택하는 것입니다. 단일 속성을 선택하는 것은 비교적 간단하지만 선택 람다에서 여러 속성을 정의하는 것은 어려울 수 있습니다.
반사 방출을 이용한 솔루션
이 문제를 해결하기 위해 반사 방출 및 보조 클래스를 사용하여 익명 유형을 동적으로 생성할 수 있습니다. 다음 코드는 이를 달성하는 방법을 보여줍니다.
동적 방법 선택
<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>
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>
사용예
여러 속성이 있는 익명 유형을 선택하려면 다음 구문을 사용하세요.
<code class="language-csharp">var v = from c in Countries where c.City == "London" select new { c.Name, c.Population };</code>
이제 다른 인스턴스와 마찬가지로 익명 유형의 속성에 액세스할 수 있습니다.
<code class="language-csharp">Console.WriteLine(v.Name); Console.WriteLine(v.Population);</code>
참고: 위의 코드 조각은 LinqRuntimeTypeBuilder
및 필요할 수 있는 기타 도우미 메서드를 포함하여 GetTypeKey
클래스의 전체 구현으로 보완되어야 합니다. 전체 구현은 복잡하며 다양한 예외 처리 및 유형 검사가 필요합니다. 이는 핵심 아이디어를 설명하기 위한 간단한 예일 뿐입니다. 실제 적용에서는 특정 요구에 따라 개선 및 오류 처리가 수행되어야 합니다. 또한, 반사 방출을 직접 사용하여 동적 유형을 구축하는 것은 성능에 영향을 미칠 수 있으므로 실제 상황에 따라 장단점을 따져봐야 합니다.
위 내용은 LINQ 표현식 트리를 사용하여 여러 속성이 있는 익명 유형을 동적으로 선택하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!