첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
본 블로그는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 블로그 콘텐츠 향상을 위해 쓰여집니다.

728x90
반응형
728x170

■ 객체 리스트 필터링 하기 예제

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

List<Student> studentList = new List<Student>
{
    new Student { Name = "강동구", Age = 70 },
    new Student { Name = "강남구", Age = 60 },
    new Student { Name = "강서구", Age = 50 },
    new Student { Name = "홍길동", Age = 20 },
    new Student { Name = "김철수", Age = 40 },
    new Student { Name = "김영희", Age = 30 }
};

List<Filter> filterList = new List<Filter>
{
    new Filter { PropertyName = "Name", OperationType = OperationType.StartsWith , Value = "강" },
    new Filter { PropertyName = "Age" , OperationType = OperationType.GreaterThan, Value = 50   }
};

var expression = ExpressionBuilder.GetExpression<Student>(filterList).Compile();

var result = studentList.Where(expression);

foreach(Student student in result)
{
    Console.WriteLine(student.Name);
}

 

■ 객체 리스트 필터링 하기

 

▶ OperationType.cs

namespace TestProject
{
    /// <summary>
    /// 연산 타입
    /// </summary>
    public enum OperationType
    {
        /// <summary>
        /// 작다.
        /// </summary>
        LessThan,

        /// <summary>
        /// 작거나 같다.
        /// </summary>
        LessThanOrEqual,

        /// <summary>
        /// 같다.
        /// </summary>
        Equals,

        /// <summary>
        /// 크거나 같다.
        /// </summary>
        GreaterThanOrEqual,

        /// <summary>
        /// 크다.
        /// </summary>
        GreaterThan,

        /// <summary>
        /// 포함한다.
        /// </summary>
        Contains,

        /// <summary>
        /// 시작한다.
        /// </summary>
        StartsWith,

        /// <summary>
        /// 끝난다.
        /// </summary>
        EndsWith
    }
}

 

▶ Filter.cs

namespace TestProject
{
    /// <summary>
    /// 필터
    /// </summary>
    public class Filter
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 속성명 - PropertyName

        /// <summary>
        /// 속성명
        /// </summary>
        public string PropertyName { get; set; }

        #endregion

        #region 연산 타입 - OperationType

        /// <summary>
        /// 연산 타입
        /// </summary>
        public OperationType OperationType { get; set; }

        #endregion

        #region 값 - Value

        /// <summary>
        /// 값
        /// </summary>
        public object Value { get; set; }

        #endregion
    }
}

 

▶ ExpressionBuilder.cs

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

namespace TestProject
{
    /// <summary>
    /// 수식 빌더
    /// </summary>
    public static class ExpressionBuilder
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// Contains 메소드 정보
        /// </summary>
        private static MethodInfo _containsMethodInfo = typeof(string).GetMethod("Contains");

        /// <summary>
        /// StartsWith 메소드 정보
        /// </summary>
        private static MethodInfo _startsWithMethodInfo = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });

        /// <summary>
        /// EndsWith 메소드 정보
        /// </summary>
        private static MethodInfo _endsWithMethodInfo = typeof(string).GetMethod("EndsWith", new Type[] { typeof(string) });

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 수식 구하기 - GetExpression<T>(filterList)

        /// <summary>
        /// 수식 구하기
        /// </summary>
        /// <typeparam name="T">타입</typeparam>
        /// <param name="filterList">필터 리스트</param>
        /// <returns>수식</returns>
        public static Expression<Func<T, bool>> GetExpression<T>(IList<Filter> filterList)
        {
            if(filterList == null || filterList.Count == 0)
            {
                return null;
            }

            ParameterExpression parameterExpression = Expression.Parameter(typeof(T), "t");
            Expression          expression          = null;

            if(filterList.Count == 1)
            {
                expression = GetExpression<T>(parameterExpression, filterList[0]);
            }
            else if(filterList.Count == 2)
            {
                expression = GetExpression<T>(parameterExpression, filterList[0], filterList[1]);
            }
            else
            {
                while(filterList.Count > 0)
                {
                    Filter filter1 = filterList[0];
                    Filter filter2 = filterList[1];

                    if(expression == null)
                    {
                        expression = GetExpression<T>(parameterExpression, filterList[0], filterList[1]);
                    }
                    else
                    {
                        expression = Expression.AndAlso(expression, GetExpression<T>(parameterExpression, filterList[0], filterList[1]));
                    }

                    filterList.Remove(filter1);
                    filterList.Remove(filter2);

                    if(filterList.Count == 1)
                    {
                        expression = Expression.AndAlso(expression, GetExpression<T>(parameterExpression, filterList[0]));

                        filterList.RemoveAt(0);
                    }
                }
            }

            return Expression.Lambda<Func<T, bool>>(expression, parameterExpression);
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Private

        #region 수식 구하기 - GetExpression<T>(parameterExpression, filter)

        /// <summary>
        /// 수식 구하기
        /// </summary>
        /// <typeparam name="T">타입</typeparam>
        /// <param name="parameterExpression">파라미터 수식</param>
        /// <param name="filter">필터</param>
        /// <returns>수식</returns>
        private static Expression GetExpression<T>(ParameterExpression parameterExpression, Filter filter)
        {
            MemberExpression   memberExpression   = Expression.Property(parameterExpression, filter.PropertyName);
            ConstantExpression constantExpression = Expression.Constant(filter.Value);

            switch(filter.OperationType)
            {
                case OperationType.LessThan           : return Expression.LessThan          (memberExpression, constantExpression);
                case OperationType.LessThanOrEqual    : return Expression.LessThanOrEqual   (memberExpression, constantExpression);
                case OperationType.Equals             : return Expression.Equal             (memberExpression, constantExpression);
                case OperationType.GreaterThanOrEqual : return Expression.GreaterThanOrEqual(memberExpression, constantExpression);
                case OperationType.GreaterThan        : return Expression.GreaterThan       (memberExpression, constantExpression);
                case OperationType.Contains           : return Expression.Call(memberExpression, _containsMethodInfo  , constantExpression);
                case OperationType.StartsWith         : return Expression.Call(memberExpression, _startsWithMethodInfo, constantExpression);
                case OperationType.EndsWith           : return Expression.Call(memberExpression, _endsWithMethodInfo  , constantExpression);
            }

            return null;
        }

        #endregion

        #region 수식 구하기 - GetExpression<T>(parameterExpression, filter1, filter2)

        /// <summary>
        /// 수식 구하기
        /// </summary>
        /// <typeparam name="T">타입</typeparam>
        /// <param name="parameterExpression">파라미터 수식</param>
        /// <param name="filter1">필터 1</param>
        /// <param name="filter2">필터 2</param>
        /// <returns>수식</returns>
        private static BinaryExpression GetExpression<T>(ParameterExpression parameterExpression, Filter filter1, Filter filter2)
        {
            Expression expression1 = GetExpression<T>(parameterExpression, filter1);
            Expression expression2 = GetExpression<T>(parameterExpression, filter2);

            return Expression.AndAlso(expression1, expression2);
        }

        #endregion
    }
}
728x90
반응형
그리드형
Posted by 사용자 icodebroker
TAG , ,

댓글을 달아 주세요