2010-05-26 5 views
3

거기에 Linq GroupBy 할 좋은 방법은 그룹화 키가 런타임에 결정됩니다? 예 : 사용자가 선택한 필드 목록에서 그룹화 키를 생성해야합니다.이 작업을 수행 할 수 있습니까? 모든 것을 문자열 테이블로 변환하면 쉽게 처리 할 수 ​​있다는 것을 알지만, 그렇지 않은 경우이를 수행 할 수있는 우아하고 똑똑한 방법이 있는지 궁금해하고 있습니다. Linq GroupBy - 런타임에 그룹화 키를 지정하는 방법?

class Item 
{ 
    public int A, B; 
    public DateTime D; 
    public double X, Y, Z; 
} 

은 내가 List<Item>data라고합니다. X의 합계를 A으로 그룹화하거나 X, YZ의 합계를 AB으로 그룹화하는 것과 같은 작업을 수행하고 싶습니다. 어떤 필드가 그룹화에 들어가야하는지는 런타임에 어떤 식 으로든 지정할 수 있어야합니다.

+0

코드 예제 제발 ... – Nix

답변

5

Dynamic LINQ 코드를 가져 와서 문자열에서 keySelector를 지정할 수있는 확장자를 사용하십시오.

var query = db.Foo.GroupBy("{0}", "GroupedProperty", groupKey); 

키로 그룹화 된 전체 개체를 다시 가져 오려는 경우 자체 확장을 추가 할 수도 있습니다.

public static IQueryable GroupByComplete(this IQueryable source, string keySelector, params object[] values) 
{ 
    if (source == null) throw new ArgumentNullException("source"); 
    if (keySelector == null) throw new ArgumentNullException("keySelector"); 
    LambdaExpression keyLambda = DynamicExpression.ParseLambda(source.ElementType, null, keySelector, values); 
    return source.Provider.CreateQuery(
     Expression.Call(
      typeof(Queryable), "GroupBy", 
      new Type[] { source.ElementType, keyLambda.Body.Type }, 
      source.Expression, Expression.Quote(keyLambda))); 
} 
+0

내가 원하는 것처럼 보입니다. 소스 코드를 보면, 상상했던 것보다 더 복잡하다고 생각합니다. 직접 작성하려고 많은 시간을 소비하지 않은 좋은 점이 있습니다. :) – toasteroven

8

당신이 필요로하는 런타임에 Func을 < 항목, TKEY >를 구성하는 것입니다

var arg = Expression.Parameter(typeof(Item), "item"); 
var body = Expression.Property(arg, "D"); 
var lambda = Expression.Lambda<Func<Item, DateTime>>(body, arg); 
var keySelector = lambda.Compile(); 

사용법 :

var result = source.GroupBy(keySelector); 

그것은 약간 얻는다 (하지만 훨씬) 더 컴파일 타임에 속성의 유형을 모르는 경우 어렵습니다.

+0

은 그 일을하려고했지만 구문을 이해할 수 없었습니다. 예제 덕분에 . – toasteroven

+0

이것은 단지 저를 도왔습니다 - 고마워요. 컴파일 타임에 Func <>의 반환 유형을 모르는 경우 어떤 옵션이 있습니까? –

+0

@ NathanRatcliff이 질문에 대한 답을 이미 알고 있습니까? – Disappointed