在LINQ中使用嵌套泛型Lambda表达式

5

我试图理解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;}
}

我正在尝试创建一个方法,它接收一个字符串,比如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");

这个 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());

以下是我尝试创建一个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());
1个回答

2

太棒了,谢谢!基本上可以了,唯一的问题是你传入的类型不正确。应该是 interiorProperty 而不是 typeof(Person)。 - Daniel Ahrnsbrak
哦,我现在明白了。请随意更正答案(社区维基)。 - Scott Rippey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接