일반적인 물체와 비교하는 LINQ 발현 트리를 어떻게 만들려면?
-
04-07-2019 - |
문제
나는 iqueryable과 Type T의 대상이 있습니다.
iqueryable (). 여기서
그래서 ...
public IQueryable<T> DoWork<T>(string fieldName)
where T : EntityObject
{
...
T objectOfTypeT = ...;
....
return SomeIQueryable<T>().Where(o => o.GetProperty(fieldName) == objectOfTypeT.GetProperty(fieldName));
}
참고로, GetProperty는 유효한 기능이 아닙니다. 이 기능을 수행하는 것이 필요합니다.
금요일 오후 뇌가 녹고 있습니까? 아니면 복잡한 일입니까?
대상이 될 수 있습니다. 다음을 수행 할 수 있습니다 ...
var matchToValue = Expression.Lambda(ParameterExpression
.Property(ParameterExpression.Constant(item), "CustomerKey"))
.Compile().DynamicInvoke();
완벽하게 작동하면 이제 두 번째 부분이 필요합니다.
edoiqueryable (). 여기서 (o => O.GetProperty (FieldName) == matchValue);
해결책
그렇게 :
var param = Expression.Parameter(typeof(T), "o");
var fixedItem = Expression.Constant(objectOfTypeT, typeof(T));
var body = Expression.Equal(
Expression.PropertyOrField(param, fieldName),
Expression.PropertyOrField(fixedItem, fieldName));
var lambda = Expression.Lambda<Func<T,bool>>(body,param);
return source.Where(lambda);
여러 표현 주제를 다루는 블로그를 시작했습니다. 여기.
문제가 발생하면 다른 옵션은 값을 추출하는 것입니다. objectOfTypeT
먼저 (반사 사용) 그런 다음 해당 값을 사용합니다. Expression.Constant
, 그러나 나는 그것이 "그대로"괜찮을 것이라고 생각합니다.
다른 팁
내가 지금까지 볼 수있는 것에서 그것은 ...
IQueryable<T>().Where(t =>
MemberExpression.Property(MemberExpression.Constant(t), fieldName) ==
ParameterExpression.Property(ParameterExpression.Constant(item), fieldName));
이것을 컴파일 할 수는 있지만 필요한 방식으로 실행되지는 않습니다.
는 어때:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public Func<T, TRes> GetPropertyFunc<T, TRes>(string propertyName)
{
// get the propertyinfo of that property.
PropertyInfo propInfo = typeof(T).GetProperty(propertyName);
// reference the propertyinfo to get the value directly.
return (obj) => { return (TRes)propInfo.GetValue(obj, null); };
}
public void Run()
{
List<Person> personList = new List<Person>();
// fill with some data
personList.Add(new Person { Name = "John", Age = 45 });
personList.Add(new Person { Name = "Michael", Age = 31 });
personList.Add(new Person { Name = "Rose", Age = 63 });
// create a lookup functions (should be executed ones)
Func<Person, string> GetNameValue = GetPropertyFunc<Person, string>("Name");
Func<Person, int> GetAgeValue = GetPropertyFunc<Person, int>("Age");
// filter the list on name
IEnumerable<Person> filteredOnName = personList.Where(item => GetNameValue(item) == "Michael");
// filter the list on age > 35
IEnumerable<Person> filteredOnAge = personList.Where(item => GetAgeValue(item) > 35);
}
이것은 동적 쿼리를 사용하지 않고 문자열별로 속성 값을 얻는 방법입니다. 단점은 Al 값이 박스형/Unboxed입니다.
제휴하지 않습니다 StackOverflow