2011-10-14 24 views
5

LINQ ifadelerini anlamaya çalışırken kendimi çıldırıyorum. Herhangi bir yardım çok takdir edilmektedir (hatta bana burada tamamen kapalı olduğumu söylüyorum).İç içe Genel Kuzudayı LINQ

ı üç sınıf

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;} 
} 

Sonra bir yaratacak böyle Locations.Name veya Locations.Floor veya Educations.SchoolName gibi bir dizede götüren bir yöntem oluşturmak çalışıyorum var diyelim dinamik linq sorgu

IEnumerable<Person> people = GetAllPeople(); 
GetFilteredResults(people, "Location.Name", "San Francisco"); 
GetFilteredResults(people, "Location.Floor", "17"); 
GetFilteredResults(people, "Educations.SchoolName", "Northwestern"); 

people.Where(p => p.Locations.Any(pl => pl.Name == Value);

Ih eşdeğerdir bir ifade oluşturmalıdır Bu GetFilteredResults(IEnumerable<Person> people, string ModelProperty, string Value) yöntem

İşte
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()); 

Ben bir IEnumerable türü için etrafında neler oynadıklarını, ama ben: ModelProperty bir dize, yani people.Where (p => p.Name == Değeri) ise bu çalışma ave şöyle sadece dış girdiklerini, doğru bir tavır sergileyen Herhangi iç alamayan nerede:

/*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()); 

cevap

1

sorun System.Linq.Enumerable.Any statik bir uzantısı yöntemi olmasıdır.

Sizin outerExpressionSystem.Linq.Enumerable.Any(IEnumerable<T>, Func<T, bool>) başvurmalıdır:

var outerExpression = Expression.Call(
    typeof(System.Linq.Enumerable), 
    "Any", 
    new Type[] { outerField.Type, innerLambda.Type }, 
    outerField, innerLambda); 

fazla bilgi için bu bağlantılardan bir göz atın:

+0

Awesome, thanks! Temelde işe yaradı, tek sorun, geçtiğiniz tür yanlıştır. İç mekanı, türkçe (Kişi) –

+0

yerine değil. Evet, şimdi anlıyorum. Cevabı düzeltmekten çekinmeyin (topluluk wiki) –