임의 속성에 의한 필터링에 대한 표현식 생성 <>
-
05-07-2019 - |
문제
객체 유형을 취하는 필터링 컨트롤을 작성하고 싶습니다. T
그리고 속성 이름과 반환 Expression<Func<T, bool>>
통과 된 속성의 가치를 점검합니다. EF가 그러한 표현을 사용할 수 없다는 것을 두려워하기 때문에 반사를 사용하고 싶지 않습니다. C#에는 속성 대표가 없기 때문에 대의원을 사용할 수 없습니다. 어떡해? 어쩌면이 컨트롤을 작성하기 위해 다른 접근법을 사용해야합니까?
반사를 사용한 첫 번째 접근법은 다음과 같습니다.
public string FilteringField { get; set; }
public Expression<Func<T, bool>> GetFilterExpression()
{
if (cmbValue.SelectedIndex == 1)
return (o => (bool)typeof(T).GetProperty(FilteringField).GetValue(o, null));
if (cmbValue.SelectedIndex == 2)
return (o => !(bool)typeof(T).GetProperty(FilteringField).GetValue(o, null));
return null;
}
해결책
여기서는 반사가 문제가되지 않습니다. EF는 차이를 알아 차릴 수 없습니다. 대의원 접근 방식은 비 스타터입니다 (EF를 언급하기 때문에). 궁극적으로, 그것은 다음과 같습니다.
public static IQueryable<T> Where<T>(this IQueryable<T> query,
string propertyName, object value)
{
PropertyInfo prop = typeof(T).GetProperty(propertyName);
var param = Expression.Parameter(typeof(T), "x");
var body = Expression.Equal(
Expression.Property(param, prop),
Expression.Constant(value, prop.PropertyType)
);
var predicate = Expression.Lambda<Func<T, bool>>(body, param);
return query.Where(predicate);
}
더 쉽게 만들 수 있습니다 Expression.PropertyOrField(propertyName)
; 내가 여기서 사용하지 않은 이유는 멤버 유형을 아는 것이 매우 편리하기 때문입니다 (prop.PropertyType
) 상수를 만들 때 - 그렇지 않으면 널에 문제가 생길 수 있습니다.
다른 팁
나는 이것을 오래된 대답이라는 것을 알고 있지만 누군가가 이것을 본다면 나는이 프로젝트를 만들었습니다.
https://github.com/poweredsoft/dynamiclinq
Nuget에서도 다운로드 할 수 있어야합니다.
https://www.nuget.org/packages/poweredsoft.dynamiclinq
그리고 당신은 단순히 할 수 있습니다
query.Where("FirstName", ConditionOperators.Equal, "David");
제휴하지 않습니다 StackOverflow