2009-08-04 14 views
6

मैं एक तरह एक बाहर पैरामीटर (एक खोज फॉर्म द्वारा पारित) के आधार पर तुलना करने के लिए कोशिश कर रहा हूँ कि तुलना के प्रकार ("%string" या "string%" या "%string%") निर्धारित करता है जैसाLinq, भाव, NHibernate और तुलना

मैं सोच रहा था निम्नलिखित दिशा में:

query = query.Where(
    Entity.StringProperty.Like("SearchString", SelectedComparsionType) 
) 

पद्धति की तरह से चयनित प्रकार वापसी के आधार पर होगा .StartsWith() या .EndsWith() या .SubString()

अभिव्यक्तियों का मेरा ज्ञान स्पष्ट रूप से बहुत दूर है, क्योंकि मैं ऐसी विधि बनाने में सक्षम नहीं हूं जो सही परिणाम प्राप्त कर सके (एसक्यूएल में सर्वर साइड तुलना StartsWith विधि के साथ)।

उत्तर

17

आसान तरीका

बस

if (comparison == ComparisonType.StartsWith) 
    query = query.Where(e => e.StringProperty.StartsWith("SearchString")); 
else if ... 

मुश्किल तरीके से

का उपयोग आप इस तरह कुछ करने के लिए चाहते हैं, या तो सुनिश्चित करें कि आपके LINQ प्रदाता के बारे में बताया जा सकता है इस नई विधि को किसी भी तरह, और यह एसक्यूएल (असंभव) में कैसे अनुवाद करता है, या आपकी विधि को LINQ प्रदाता तक पहुंचने से रोकता है, और प्रदाता को कुछ समझता है (हे आरडी)। उदाहरण के लिए,

query.Where(e => CompMethod(e.StringProperty, "SearchString", comparsionType)) 

के बजाय के लिए आप इस तरह से

var query = from e in source.WhereLike(
       e => e.StringProperty, "SearchString", comparsionType) 
      where e.OtherProperty == 123 
      orderby e.StringProperty 
      select e; 

public enum ComparisonType { StartsWith, EndsWith, Contains } 

public static class QueryableExtensions 
{ 
    public static IQueryable<T> WhereLike<T>(
     this IQueryable<T> source, 
     Expression<Func<T, string>> field, 
     string value, 
     SelectedComparisonType comparisonType) 
    { 
     ParameterExpression p = field.Parameters[0]; 
     return source.Where(
      Expression.Lambda<Func<T, bool>>(
       Expression.Call(
        field.Body, 
        comparisonType.ToString(), 
        null, 
        Expression.Constant(value)), 
      p)); 
    } 
} 

तुम भी अतिरिक्त मापदंड जोड़ सकते हैं निम्न कोड के साथ की तरह

var query = source.WhereLike(e => e.StringProperty, "SearchString", comparsionType) 

कुछ बना सकते हैं बहुत, बहुत मुश्किल तरीके से

यह (तकनीकी) अभिव्यक्ति पेड़ के पुनर्लेखन के लिए पहले प्रदाता इसे देखता है, तो आप क्वेरी आप पहली जगह में मन में था का उपयोग कर सकते संभव होगा, लेकिन आप ' d एक Where(this IQueryable<EntityType> source, Expression<Func<EntityType, bool>> predicate)

  • करने के लिए है बनाने के बीच में रोकने का Queryable.Where,
  • अभिव्यक्ति पेड़ को फिर से लिखने, String तरीकों में से एक के साथ अपने CompMethod की जगह, जहाँ भी यह है,
  • रीयल लिखित अभिव्यक्ति के साथ मूल Queryable.Where पर कॉल करें,
  • और सबसे पहले, ऊपर दी गई एक्सटेंशन विधि का पालन करने में सक्षम हो जाएं!

लेकिन संभवतः यह आपके मन में जो कुछ भी था उसके लिए बहुत जटिल है।

+0

रुबेन: घटनात्मक, यह एक स्पष्टीकरण का एक नरक है - पूर्ण, समझने योग्य, पूरी तरह से और बिल्कुल जो मैं ढूंढ रहा था, धन्यवाद। मैं उनकी सहायता के लिए दूसरों को भी धन्यवाद देना चाहूंगा। –

-1

आप इस समस्या को हल करने के लिए Regex का उपयोग कर बेहतर रहेगा।

query = query.Where(
Entity.StringProperty.Contains("SearchString") 
) 

यह करने के लिए नक्शे चाहिए::

+0

इसका परिणाम डेटाबेस LIKE ऑपरेटर नहीं होगा, जो मुझे लगता है कि ओपी चाहता है – MattH

1

की तरह आप का उपयोग करना चाहते किया जाना चाहिए लगता है

WHERE StringProperty LIKE '%SearchString%' 

यह भी इस तरह के "श्री एस.एम.% वें?" के रूप में अधिक उन्नत खोज मास्क के लिए काम करना चाहिए , लेकिन मुझे अभी तक किसी भी खोज तार का परीक्षण नहीं करना पड़ा है।


अद्यतन: पर ऑप्स संपादित आधार

ऐसा लगता है क्या आप के लिए पूछ रहे हैं निम्नलिखित की तरह कुछ है की तरह:

public enum SelectedComparsionType 
    { 
     StartsWith, 
     EndsWith, 
     Contains 
    } 

public static bool Like(this string searchString, string searchPattern, SelectedComparsionType searchType) 
{ 
    switch (searchType) 
    { 
     case SelectedComparsionType.StartsWith: 
      return searchString.StartsWith(searchPattern); 
     case SelectedComparsionType.EndsWith: 
      return searchString.EndsWith(searchPattern); 
     case SelectedComparsionType.Contains: 
     default: 
      return searchString.Contains(searchPattern); 
    } 
} 

इस के रूप में आप की आवश्यकता होती है आप कोड लिखने की अनुमति होगी , यानी:

query = query.Where(
Entity.StringProperty.Like("SearchString", SelectedComparsionType.StartsWith) 
) 

हालांकि, व्यक्तिगत रूप से, मैं चयनित स्ट्रिंग फ़ंक्शन पर सीधे कॉल के साथ चयनित कॉम्पर्सन टाइप के किसी भी उपयोग को प्रतिस्थापित कर दूंगा। आई

query = query.Where(
Entity.StringProperty.StartsWith("SearchString") 
) 

चूंकि यह अभी भी एक SQL 'LIKE' क्वेरी पर मैप करेगा।

0

यह वही है जो मुझे दिमाग में था, धन्यवाद। मेरे पास पहले से ही कुछ लिखा गया था, लेकिन यह एसक्यूएल में अनुवाद नहीं किया था। उदाहरण के लिए, यह काम करता है, तो मैं इस सीधे किया:

Entity.StringProperty.EndsWith("SearchString"); 

यह है कि अगर मैं एक समर्पित विधि का इस्तेमाल किया काम नहीं किया:

CompMethod("BaseString","SearchString",SelectedComparsionType.EndsWith) 

मुझे लगता है कि यह शायद अभिव्यक्ति मूल्यांकन के साथ कुछ करने के लिए है, मैं मुझे यकीन नहीं है कि क्या।

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