데이터를 조회할때 조회 조건을 동적으로 받아 조회하는 방법입니다.
Expressions 을 이용해 처리가 가능하면 문자열인 경우는 숫자 처럼 비교가 불가능 하므로 다르게 처리해야합니다.
조건은 conditions 에 들어가게 되면 여기에는 조건필드와 값 , 비교연산자가 들어가게됩니다.
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;
public class Program
{
public class Item
{
public int Value1 { get; set; }
public int Value2 { get; set; }
public string Name { get; set; } // 문자열 컬럼 추가
}
public static void Main()
{
var items = new List<Item>
{
new Item { Value1 = 5, Value2 = 10, Name = "apple" },
new Item { Value1 = 10, Value2 = 15, Name = "banana" },
new Item { Value1 = 20, Value2 = 25, Name = "cherry" }
};
// 각 컬럼에 대해 비교할 조건 (문자열 포함)
var conditions = new List<(string PropertyName, string Operator, object Value)>
{
("Value1", ">", 5),
("Value2", "<=", 20),
("Name", "<", "cherry") // 문자열 비교
};
// 조건을 결합한 Expression을 생성
var predicate = BuildDynamicQuery<Item>(conditions);
// LINQ 쿼리 실행
var filteredItems = items.AsQueryable().Where(predicate).ToList();
// 필터링된 결과 출력
foreach (var item in filteredItems)
{
Console.WriteLine($"Value1: {item.Value1}, Value2: {item.Value2}, Name: {item.Name}");
}
}
public static Expression<Func<T, bool>> BuildDynamicQuery<T>(List<(string PropertyName, string Operator, object Value)> conditions)
{
// 매개 변수
var parameter = Expression.Parameter(typeof(T), "x");
// 조건들을 결합한 Expression을 생성
Expression body = null;
foreach (var condition in conditions)
{
var member = Expression.Property(parameter, condition.PropertyName);
var constant = Expression.Constant(condition.Value);
Expression comparison;
// 문자열인지 확인
if (member.Type == typeof(string))
{
// 문자열 비교 연산을 처리하기 위해 string.Compare 메서드 사용
var compareMethod = typeof(string).GetMethod("Compare", new[] { typeof(string), typeof(string) });
var compareExpression = Expression.Call(null, compareMethod, member, constant);
comparison = condition.Operator switch
{
"=" => Expression.Equal(member, constant),
">" => Expression.GreaterThan(compareExpression, Expression.Constant(0)),
"<" => Expression.LessThan(compareExpression, Expression.Constant(0)),
">=" => Expression.GreaterThanOrEqual(compareExpression, Expression.Constant(0)),
"<=" => Expression.LessThanOrEqual(compareExpression, Expression.Constant(0)),
"!=" => Expression.NotEqual(member, constant),
_ => throw new NotSupportedException($"Unsupported operator: {condition.Operator}")
};
}
else
{
// 문자열이 아닌 경우 기본 연산자 사용
comparison = condition.Operator switch
{
"=" => Expression.Equal(member, constant),
">" => Expression.GreaterThan(member, constant),
"<" => Expression.LessThan(member, constant),
">=" => Expression.GreaterThanOrEqual(member, constant),
"<=" => Expression.LessThanOrEqual(member, constant),
"!=" => Expression.NotEqual(member, constant),
_ => throw new NotSupportedException($"Unsupported operator: {condition.Operator}")
};
}
// 조건들을 And로 결합
body = body == null ? comparison : Expression.AndAlso(body, comparison);
}
// 최종 Expression 생성
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
}
zip 파일을 wav 로 변환하고 wav 파일을 다시 zip 파일로 변환하기 (0) | 2024.09.19 |
---|---|
Python 의 numpy 함수를 C# 에서 사용하고 싶을 때 NumSharp (0) | 2024.09.11 |
Naver 사이트 열어 특정 단어 검색하기 (0) | 2024.08.22 |
Quartz Scheduler misfire 처리하기 - 즉시 실행 방지 (0) | 2024.08.21 |
C# Double/float 연산 결과가 이상할 때 처리 방법 (부동소수점 연산) (0) | 2024.07.16 |