2013-04-10 2 views
5

이 같은 몇 가지 일반적인 검색 방법 작성해야합니다 :C# 일반 Linq는 쿼리

public List<T> Search<T>(SearchParamsBase searchParams) 
{ 
    using (var context = new TestEntities()) 
    { 
     var dataType = TypeMap.Get(typeof (T)); 
     var dataSet = context.Set(dataType); 

     var searchQuery = CreateQuery((IEnumerable<object>) dataSet), searchParams) 

     return searchQuery.ToList() 
    } 
} 

을 나는 IEnumerable 개체를 필터링해야하는 기능 CreateQuery() 있습니다. 이 기능은 모든 클래스에 따라 다릅니다. 예 :

CreateQuery(IEnumerable<object> collection, SearchParamsBase searchParams) 
{ 
    var search = (SomeSearchImplementation)searchParams; 
    // filter 
    collection = collection.Where(x => x.Name == search.Name); 
    // select page 
    collection = collection.Skip(search.Page * search.CountPerPage); 
    collection = collection.Take(search.CountPerPage); 
    // order by and so on 
    // ... 
    return collection; 
} 

이 아이디어를 올바르게 구현하려면 어떻게해야합니까?

답변

7

기본적으로 여기에서 수행하려는 작업은 LINQ 쿼리를 동적으로 구성하는 것입니다. 이렇게하려면 런타임에 표현식 트리를 수정/빌드해야합니다. 당신은 식 트리에 익숙하지 않은 및 Expression<T> 유형이 글과 "참조"절에 참조 된 페이지 권장 경우 : 이제

http://msdn.microsoft.com/en-us/library/bb397951.aspx

을 이제 기본 개념은,의 동적 정렬을 구현 할 수있다. 아래의 방법은 IQueryable<T>의 확장입니다. 즉, 목록에만 적용되는 것이 아니라 모든 LINQ 데이터 소스에 적용되므로 데이터베이스에 대해 직접 사용할 수도 있습니다 (페이징 및 정렬의 경우 메모리 작업보다 효율적입니다) .

dataSet.OrderByDynamic("Name", false) 
: ascending 위해 재산 Name하여 데이터 세트를 주문

public static IQueryable<T> OrderByDynamic<T>(this IQueryable<T> query, string sortColumn, bool descending) 
{ 
    // Dynamically creates a call like this: query.OrderBy(p => p.SortColumn) 
    var parameter = Expression.Parameter(typeof(T), "p"); 

    string command = "OrderBy"; 

    if (descending) 
    { 
     command = "OrderByDescending"; 
    } 

    Expression resultExpression = null;  

    var property = typeof(T).GetProperty(sortColumn); 
    // this is the part p.SortColumn 
    var propertyAccess = Expression.MakeMemberAccess(parameter, property); 

    // this is the part p => p.SortColumn 
    var orderByExpression = Expression.Lambda(propertyAccess, parameter); 

    // finally, call the "OrderBy"/"OrderByDescending" method with the order by lamba expression 
    resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { typeof(T), property.PropertyType }, 
     query.Expression, Expression.Quote(orderByExpression)); 

    return query.Provider.CreateQuery<T>(resultExpression); 
} 

지금이 코드를 작성할 수 있습니다 : 방법은 당신에 의해 주문하려는 속성 이름과 정렬 방향 (상승/하강)을한다

동적 필터링을위한 확장 방법을 만드는 것은 동일한 패턴을 따릅니다. 위의 코드를 이해하면 문제가되지 않습니다.