Dan*_*rak 5 .net c# linq lambda expression-trees
我正在疯狂地试图理解LINQ中的表达式.非常感谢任何帮助(甚至告诉我,我完全不在这里).
假设我有三节课
public class Person
{
public string Name { get; set;}
public IEnumerable<PersonLocation> Locations { get; set;}
public IEnumerable<PersonEducation> Educations { get; set:}
}
public class PersonLocation
{
public string Name { get; set;}
public string Floor { get; set;}
public string Extension { get; set;}
}
public class PersonEducation
{
public string SchoolName { get; set;}
public string GraduationYear { get; set;}
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个接收字符串的方法,例如Locations.Name或Locations.Floor,或Educations.SchoolName,然后创建一个动态linq查询
IEnumerable<Person> people = GetAllPeople();
GetFilteredResults(people, "Location.Name", "San Francisco");
GetFilteredResults(people, "Location.Floor", "17");
GetFilteredResults(people, "Educations.SchoolName", "Northwestern");
Run Code Online (Sandbox Code Playgroud)
此GetFilteredResults(IEnumerable<Person> people, string ModelProperty, string Value)方法应创建一个大致相当于的表达式people.Where(p => p.Locations.Any(pl => pl.Name == Value);
如果ModelProperty是一个字符串,那么我有这个工作,即people.Where(p => p.Name == Value)如下所示:
string[] modelPropertyParts = ModelProperty.Split('.');
var prop = typeof(Person).GetProperty(modelPropertyParts[0]);
var sourceParam = Expression.Parameter(typeof(Person), "person");
var expression = Expression.Equal(Expression.PropertyOrField(sourceParam, modelPropertyParts[0]), Expression.Constant(option.Name));
var whereSelector = Expression.Lambda<Func<Person, bool>>(orExp, sourceParam);
return people.Where(whereSelector.Compile());
Run Code Online (Sandbox Code Playgroud)
这是我一直在玩IEnumerable类型的东西,但我只是无法获得内部Any,这似乎是正确的,挂钩到外部Where:
/*i.e. modelPropertyParts[0] = Locations & modelPropertyParts[1] = Name */
string[] modelPropertyParts = ModelProperty.Split('.');
var interiorProperty = prop.PropertyType.GetGenericArguments()[0];
var interiorParameter = Expression.Parameter(interiorProperty, "personlocation");
var interiorField = Expression.PropertyOrField(interiorParameter, modelPropertyParts[1]);
var interiorExpression = Expression.Equal(interiorField, Expression.Constant(Value));
var innerLambda = Expression.Lambda<Func<PersonLocation, bool>>(interiorExpression, interiorParameter);
var outerParameter = Expression.Parameter(typeof(Person), "person");
var outerField = Expression.PropertyOrField(outerParameter, modelPropertyParts[0]);
var outerExpression = ??
var outerLambda == ??
return people.Where(outerLambda.Compile());
Run Code Online (Sandbox Code Playgroud)
问题是这System.Linq.Enumerable.Any是一个静态扩展方法。
您outerExpression必须参考System.Linq.Enumerable.Any(IEnumerable<T>, Func<T, bool>):
var outerExpression = Expression.Call(
typeof(System.Linq.Enumerable),
"Any",
new Type[] { outerField.Type, innerLambda.Type },
outerField, innerLambda);
Run Code Online (Sandbox Code Playgroud)
查看这些链接以获取更多信息:
| 归档时间: |
|
| 查看次数: |
1118 次 |
| 最近记录: |