LINQ中的嵌套泛型lambda

本文关键字:泛型 lambda 嵌套 LINQ | 更新日期: 2023-09-27 18:11:13

为了理解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;}
}

我试图创建一个方法,在一个字符串,如位置。名称或位置。地板,或教育。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是一个字符串,即人。其中(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());

LINQ中的嵌套泛型lambda

问题是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);

查看以下链接获取更多信息:

  • msdn Expression.Call(Type, String, Type[], params Expression[])
  • 一些有用的,类似的例子。