문제

객체 유형을 취하는 필터링 컨트롤을 작성하고 싶습니다. 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");
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top