LINQ

2011-10-14 7 views
5

में नेस्टेड जेनेरिक लैम्ब्डास मैं LINQ में अभिव्यक्तियों को समझने की कोशिश कर पागल हूं। किसी भी मदद की बहुत सराहना की जाती है (यहां तक ​​कि मुझे यह भी बता रहा है कि मैं यहां आधार से पूरी तरह से बंद हूं)।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.Name == मूल्य) है इस तरह दिखता है:

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 प्रकार के लिए के साथ चारों ओर खेल रहे हैं, लेकिन मैं बस किसी भी आंतरिक है, जो सही लगता है, बाहरी में झुका नहीं मिल सकता है कहां:

/*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

समस्या 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); 

अधिक जानकारी के लिए इन लिंक पर एक नज़र डालें:

+0

बहुत बढ़िया, धन्यवाद! यह मूल रूप से काम करता है, केवल एक ही समस्या यह है कि आप जिस प्रकार में गुजरते हैं वह गलत है। यह टाइपऑफ (व्यक्ति) –

+0

के बजाय इंटीरियरप्रोपर्टी होना चाहिए ओह हाँ, अब मैं देखता हूं। उत्तर को सही करने के लिए स्वतंत्र महसूस करें (समुदाय विकी) –

संबंधित मुद्दे