■ 객체 리스트를 필터링하는 방법을 보여준다.
▶ 객체 리스트 필터링 하기 예제 (C#)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
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 } } |