2009-08-07 3 views
4

다양한 클래스에 대한 동적 필터를 만들려고합니다. 우리는 런타임에 어떤 유형을 다루는 지 알 것입니다. ColumnName이 실제 열 (문자열 값이 아님)이되어야합니다.동적 목록 용 <T>

문자열을 열로 쉽게 변환 할 수 있습니까?

public static List<T> Filter<T> 
    (this List<T> Source, string ColumnName, 
    string TypeOfCompare, string CompValue) 
{ 
    IQueryable<T> matches = Source.AsQueryable(); 

    if (ColumnName.Length > 0) 
    { 
     matches = (IEnumerable)matches.Where(a => ColumnName == CompValue) 
    } 

    List<T> ReturnList2 = new List<T>(); 
    ReturnList2 = matches.ToList(); 
    return ReturnList2; 
} 

답변

9

기본적으로 표현식 트리를 만들어야합니다. 다행히도 Expression.Property을 사용하는 것은 그리 어렵지 않습니다. 그것을 Queryable.Where으로 전달하거나 컴파일하여 Enumerable.Where으로 전달하십시오. (물론 당신은 당신이 만들려고 노력하고 비교의 종류에 따라,뿐만 아니라 Expression.Equal 같은 것을 사용해야합니다.)

CompValue는 실제 값을 될 운명인가? TypeOfCompare은 무엇을 의미합니까?

LINQ to Entities가이 항목에 적합한 지 잘 모르겠습니다 ... LINQ to Objects 만 사용하고 있습니다.

편집 : 좋아요, 여기 샘플이 있습니다. 당신이 평등을 원한다고 가정하지만, 그렇게한다면 당신이 원하는 것을합니다. 대신 문자열 ColumnName

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Linq.Expressions; 

static class Extensions 
{ 
    public static List<T> Filter<T> 
     (this List<T> source, string columnName, 
     string compValue) 
    { 
     ParameterExpression parameter = Expression.Parameter(typeof(T), "x"); 
     Expression property = Expression.Property(parameter, columnName); 
     Expression constant = Expression.Constant(compValue); 
     Expression equality = Expression.Equal(property, constant); 
     Expression<Func<T, bool>> predicate = 
      Expression.Lambda<Func<T, bool>>(equality, parameter); 

     Func<T, bool> compiled = predicate.Compile(); 
     return source.Where(compiled).ToList(); 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     var people = new[] { 
      new { FirstName = "John", LastName = "Smith" }, 
      new { FirstName = "John", LastName = "Noakes" }, 
      new { FirstName = "Linda", LastName = "Smith" }, 
      new { FirstName = "Richard", LastName = "Smith" }, 
      new { FirstName = "Richard", LastName = "Littlejohn" }, 
     }.ToList(); 

     foreach (var person in people.Filter("LastName", "Smith")) 
     { 
      Console.WriteLine(person); 
     } 
    } 
} 
+0

오른쪽 ... Linq to Objects ... 우리는 (firstname, lastname, phone)과 같은 데이터를 포함하는 클래스가 있으며 CompValue는 우리가 찾고있는 실제 값입니다 match ... 그래서 예제는 ... personCollection = personCollection.Filter ("LastName", "Smith"); 그리고 우리는 스미스의 "필터링 된"컬렉션을 반환 할 것입니다 ... 감사합니다 –

+0

... 감사합니다 존. John K. –

0

을, 당신은 할 수 없습니다 : 당신은 어떤 주어진 이름/값 조합에 대한 대리자를 캐시 할 수 있습니다 - 나는 모든 시간이 식 트리를 컴파일의 성능에 미치는 영향이 무엇인지 모르는 그 열에 대한 선택기를 전달하십시오 (이것이 항상 가능한 것은 아니라는 것을 알고 있지만, 그렇다면 ...). 그럼 당신이 사용할 수 있어요.

그런데 코드가 너무 복잡합니다. 이 작동합니다 :

var result = myList.Filter(x => x.ColumnName, "foo"); 
0

는이 같은 뭔가를 찾고있다 : 다음과 같이

public static List<T> Filter<T>(
    this List<T> Source, Func<T, string> selector, string CompValue) 
{ 
    return Source.Where(a => selector(a) == CompValue).ToList(); 
} 

그런 다음 코드를 호출 할 수 http://naspinski.net/post/Writing-Dynamic-Linq-Queries-in-Linq-to-Entities.aspx 그렇지 않으면 당신은 다음과 같이 개별적으로 각각의 경우를 처리 할 수있다 :

if (columnName == "blah") 
    matches = matches.Where(i => i.Blah == Value); 
if (columnName == "name") 
    matches = matches.Where(i => i.Name == Value); 
+0

내 ** 일치 ** 변수가 런타임 유형의 동적 목록 유형 인 경우 어떻게해야합니까? –