2015-08-21 8 views
14

द्वारा इकाई फ्रेमवर्क फ़िल्टर डेटा मैं अपनी तालिका में कुछ फ़िल्टर डेटा संग्रहीत कर रहा हूं। मुझे इसे और स्पष्ट करने दें: मैं डेटाबेस में कुछ where क्लॉज और उनके मानों को संग्रहीत करना चाहता हूं और जब मैं डेटाबेस से डेटा पुनर्प्राप्त करना चाहता हूं तो उनका उपयोग करना चाहता हूं। अब जब मैं people मेज से डेटा पुनः प्राप्तस्ट्रिंग एसक्यूएल

"age" , "> 70" 
"gender" , "= male" 

मैं इन फिल्टर मेरी डेटा फ़िल्टर करना प्राप्त करना चाहते हैं:

उदाहरण के लिए, एक people तालिका (इकाई सेट) और उस पर कुछ फिल्टर एक और तालिका में करने पर विचार ।

मुझे पता है कि मैं एक स्ट्रिंग के रूप में एक SQL क्वेरी उत्पन्न कर सकता हूं और निष्पादित करता हूं लेकिन क्या ईएफ, LINQ में कोई और बेहतर तरीका है?

+0

इकाई ढांचे के साथ आप इसका उपयोग कहां कर सकते हैं: ob.Where (p => p.age> 70 && लिंग == "पुरुष")। – MaticDiba

+0

आयु और 70 स्ट्रिंग फ़िल्टर हैं जिन्हें डीबी से पुनर्प्राप्त किया जाता है। तो मैं कोड की इस पंक्ति को कैसे लिख सकता हूं?कृपया प्रश्न फिर से पढ़ें। धन्यवाद। – ConductedClever

+0

आप इस [अभिव्यक्ति निर्माता] का उपयोग कर सकते हैं (http://www.codeproject.com/Tips/582450/Build-Where-Clause- गतिशील-in-Linq) –

उत्तर

8

एक समाधान हो सकता है आप Dynamic Linq Library उपयोग करने के लिए, इस लाइब्रेरी का उपयोग कर रहा है:

filterTable = //some code to retrive it 
var whereClause = string.Join(" AND ", filterTable.Select(x=> x.Left + x.Right)); 
var result = context.People.Where(whereClause).ToList(); 

यह मानते हुए कि फिल्टर तालिका स्तंभ Left और Right है और आप AND द्वारा फिल्टर शामिल करना चाहते हैं।

मेरे सुझाव, फिल्टर तालिका में अधिक विवरण शामिल करने के लिए है, उदाहरण के लिए ऑपरेंड से ऑपरेटरों को अलग करने और एक स्तंभ में शामिल होने के निर्धारित करता है जोड़ने है And या OR और एक स्तंभ है कि अन्य पंक्ति जो इस एक मिलती है निर्धारित करता है। यदि आप (A and B)Or(C and D) जैसे अधिक जटिल प्रश्नों को संभालना चाहते हैं तो आपको पेड़ की संरचना की आवश्यकता है।

फ़िल्टर समाधान से अभिव्यक्ति वृक्ष बनाने का एक और समाधान है।

var arg = Expression.Parameter(typeof(People)); 
Expression whereClause; 
for(var row in filterTable) 
{ 
    Expression rowClause; 
    var left = Expression.PropertyOrField(arg, row.PropertyName); 
    //here a type cast is needed for example 
    //var right = Expression.Constant(int.Parse(row.Right)); 
    var right = Expression.Constant(row.Right, left.Member.MemberType); 
    switch(row.Operator) 
    { 
      case "=": 
       rowClause = Expression.Equal(left, right); 
      break; 
      case ">": 
       rowClause = Expression.GreaterThan(left, right); 
      break; 
      case ">=": 
       rowClause = Expression.GreaterThanOrEqual(left, right); 
      break; 
     } 
     if(whereClause == null) 
     { 
      whereClause = rowClause; 
     } 
     else 
     { 
      whereClause = Expression.AndAlso(whereClause, rowClause); 
     } 
} 
var lambda = Expression.Lambda<Func<People, bool>>(whereClause, arg); 
context.People.Where(lambda); 

यह बहुत ही सरल उदाहरण आदेश में इस प्रश्नों के सभी प्रकार के लिए काम करता है बनाने के लिए कई सत्यापन प्रकार कास्टिंग और ..., आपको क्या करना चाहिए है: यहाँ एक सरल उदाहरण है।

+3

आपका उदाहरण ओपी को देखने में मदद करेगा कि क्या करने की आवश्यकता है। मुझे रुचि रखने वाले पाठकों के लिए अपना अगला कदम जानने के लिए कुछ सुझाव दें: [दुभाषिया पैटर्न] (https://en.wikipedia.org/wiki/Interpreter_pattern) या [विज़िटर पैटर्न] पर विचार करें (https: //en.wikipedia .org/wiki/Visitor_pattern) ([तुलना] (http://www.researchgate.net/profile/Tijs_Van_der_Storm/publication/220878226_A_Case_of_Visitor_versus_Interpreter_Pattern/links/09e4150981f71beda3000000.pdf))। यह आमतौर पर एक डिजाइन को अधिक आसानी से बनाए रखने योग्य बनाता है, लेकिन विचार बिल्कुल वही है। – tne

+0

आपके दोनों उत्तर शानदार हैं। लेकिन मुझे लगता है कि मुझे दूसरा एक और पसंद है। बहुत बहुत धन्यवाद। – ConductedClever

+0

आपका स्वागत है। दूसरा एक और चुनौतीपूर्ण है, मैं आपको अपनी हिम्मत के लिए बधाई देता हूं !! –

3

यह एक दिलचस्प सवाल है। सबसे पहले, सुनिश्चित करें कि आप अपने साथ ईमानदार हैं: आप एक नई क्वेरी भाषा बना रहे हैं, और यह एक मामूली कार्य नहीं है (हालांकि आपके अभिव्यक्तियों को तुच्छ लग सकता है)।

यदि आप निश्चित हैं कि आप कार्य को कम करके कम नहीं कर रहे हैं, तो आप LINQ expression trees (reference documentation) देखना चाहेंगे।

दुर्भाग्य से, यह काफी व्यापक विषय है, मैं आपको मूल बातें सीखने के लिए प्रोत्साहित करता हूं और आने वाले अधिक विशिष्ट प्रश्न पूछता हूं। आपका लक्ष्य अपने फ़िल्टर अभिव्यक्ति रिकॉर्ड (आपकी तालिका से प्राप्त) की व्याख्या करना है और वे अनुमानित भविष्यवाणी के लिए LINQ अभिव्यक्ति वृक्ष बनाते हैं। फिर आप पेड़ को Where() कॉल सामान्य रूप से पास कर सकते हैं।

2

बिना जाने क्या आपके यूआई यहाँ की तरह दिखता है की एक सरल उदाहरण है कि मैं क्या Serialize.Linq पुस्तकालय

public void QuerySerializeDeserialize() 
    { 
      var exp = "(User.Age > 7 AND User.FirstName == \"Daniel\") OR User.Age < 10"; 
      var user = Expression.Parameter(typeof (User), "User"); 
      var parsExpression = 
        System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] {user}, null, exp); 

      //Convert the Expression to JSON 
      var query = e.ToJson(); 

      //Deserialize JSON back to expression 
      var serializer = new ExpressionSerializer(new JsonSerializer()); 
      var dExp = serializer.DeserializeText(query); 

      using (var context = new AppContext()) 
      { 
       var set = context.Set<User>().Where((Expression<Func<User, bool>>) dExp); 
      } 

    } 

के बारे में मेरी टिप्पणी में के बारे में बात कर रहा था आप शायद प्रतिबिंब का उपयोग करें और अपने सामान्य LINQ क्वेरी के आधार पर लागू अधिक सजावटी प्राप्त कर सकते हैं अभिव्यक्ति से आने वाले प्रकार। इस तरह आप अभिव्यक्ति कास्टिंग से बच सकते हैं जैसे मैंने उदाहरण के अंत में किया था।

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