2017-09-14 15 views
0

WHERE 절에서 or 연산과 함께 사용해야하는 필터 또는 표현식 집합을 기반으로 데이터를 필터링하는 방법은 무엇입니까?여러 복잡한 절이 OR 연산과 결합 된 데이터 필터링 함수

class DTOFilter 
{ 
    public string Domain { get; set; } 
    public string Mobile { get; set; } 
} 

필터의 목록을 다음 방식에 따라 Users 목록을 필터링 할 필요 : 분명히

u=> 
(u.Email.Contains(filters[0].Domain) && u.PhoneNumber.StartsWith(filters[0].Mobile)) || 
(u.Email.Contains(filters[1].Domain) && u.PhoneNumber.StartsWith(filters[1].Mobile)) || 
... 

그에서보기 자동 구축해야

예를 들어

는, 클래스가 형태 :

db.Users.Where(filters.Filter<Users, DTOFilter>(
         (u, f) => u.Email.Contains(f.Domain) 
           && u.PhoneNumber.StartsWith(f.Mobile)) 
       .Or()) 

답변

1

해당 작업을 수행하려면 2 가지 기능 :

  1. Or 표현 기능에 가입

또는 기능 데이터 분할 기능은 표현의 모음을 거친 (((expression1 or expression2) or expression3) or expression4)

public static Expression<Func<T, bool>> Or<T>(
    this IEnumerable<Expression<Func<T, bool>>> source) 
    { 
     var expressions = source.ToList(); 
     if (expressions.Count == 0) 
      return x => false; 

     var orExpression = expressions 
      .Select(e => e.Body) 
      .Aggregate((a, b) => Expression.OrElse(a, b)); 
     var parameter = expressions.First().Parameters.First(); 
     return Expression.Lambda<Func<T, bool>>(orExpression, parameter); 
    } 

이 같은 Or 식을 조인

  • 필터 함수는 이미 필터가 유효한 표현식 인 경우 이미 사용할 수 있습니다.

    필터 분리 데이터 함수는 선택기 식을 곱하고 결과 식 매개 변수를 정확한 개체 값으로 대체해야합니다. 필터 데이터 인구는 기능 수행됩니다

    public static IEnumerable<Expression<Func<T, bool>>> Filter<T, TData>(
        this IEnumerable<TData> data, 
        Expression<Func<T,TData, bool>> selector) 
    { 
        var parameter = selector.Parameters.First(p => p.Type.IsAssignableFrom(typeof(T))); 
    
        return data.Select(item => Expression.Lambda<Func<T, bool>>(
         new DataVisitor<TData>(item).Visit(selector.Body), parameter)); 
    } 
    

    다음 방문자 구현이 정확한 값으로 매개 변수를 대체하는 데 도움이 :

    public class DataVisitor<T> : ExpressionVisitor 
    { 
        private readonly ConstantExpression _data; 
    
        public DataVisitor(T dataItem) 
        { 
         _data = Expression.Constant(dataItem); 
        } 
    
        protected override Expression VisitParameter(ParameterExpression node) 
        { 
          return node.Type.IsAssignableFrom(typeof(T)) 
            ? _data : base.VisitParameter(node); 
        } 
    } 
    

    빌드 표현식은 EF에 의해 구문 분석 할 수있는 올바른 람다 식이다 표현 트리 파서.