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

----------------------------------------------------------------------------------------------------

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

    }

}

 

----------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요