LINQ to Entities विधि को नहीं पहचानता है


116

Linq क्वेरी करने का प्रयास करते समय मुझे निम्न त्रुटि मिल रही है:

LINQ to Entities विधि 'बूलियन IsCharityMatching (System.String, System.String)' विधि को नहीं पहचानता है, और इस पद्धति का स्टोर अभिव्यक्ति में अनुवाद नहीं किया जा सकता है।

मैंने पिछले प्रश्नों के बहुत सारे पढ़े हैं जहाँ लोगों को एक ही त्रुटि मिलती है, और अगर मैं इसे सही ढंग से समझता हूँ तो यह है क्योंकि LINQ to Entities को पूरे linq क्वेरी एक्सप्रेशन को सर्वर क्वेरी में अनुवादित करने की आवश्यकता होती है, और इसलिए आप एक बाहरी विधि को कॉल नहीं कर सकते हैं इस में। मैं अपने परिदृश्य को अभी तक काम करने वाली चीज़ में परिवर्तित नहीं कर पाया हूं, और मेरा दिमाग पिघलना शुरू हो गया है, इसलिए मुझे उम्मीद थी कि कोई मुझे सही दिशा में ले जा सकता है। हम एंटिटी फ्रेमवर्क और विनिर्देशन पैटर्न का उपयोग कर रहे हैं (और मैं दोनों के लिए नया हूं)।

यहां वह कोड है जो विनिर्देश का उपयोग करता है:

ISpecification<Charity> specification = new CharitySearchSpecification(charityTitle, charityReference);

charities = charitiesRepository.Find(specification).OrderBy(p => p.RegisteredName).ToList();

यहाँ linq अभिव्यक्ति है:

public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
    return p => p.IsCharityMatching(this.charityName, this.charityReference);
}

यहाँ IsCharityMatching विधि है:

public bool IsCharityMatching(string name, string referenceNumber)
{
    bool exists = true;

    if (!String.IsNullOrEmpty(name))
    {
        if (!this.registeredName.ToLower().Contains(name.ToLower()) &&
            !this.alias.ToLower().Contains(name.ToLower()) &&
           !this.charityId.ToLower().Contains(name.ToLower()))
        {
            exists = false;
        }
    }

    if (!String.IsNullOrEmpty(referenceNumber))
    {
        if (!this.charityReference.ToLower().Contains(referenceNumber.ToLower()))
        {
            exists = false;
        }
    }

    return exists;
}

यदि आपको और भी किसी जानकारी की ज़रूरत है तो मुझे बताएं।

बहुत धन्यवाद,

Annelie



यह भी जाँच करेगा, धन्यवाद!
annelie

1
यह देखना अच्छा होगा कि आप इसका उपयोग कैसे कर रहे हैं Find()जब आप IsSatisfied()इसके अंदर कैसे उपयोग करते हैं ।
एलिसन

जवाबों:


124

जैसा कि आप समझ चुके हैं, एंटिटी फ्रेमवर्क वास्तव में आपके C # कोड को उसकी क्वेरी के भाग के रूप में नहीं चला सकता है। इसे क्वेरी को वास्तविक SQL कथन में बदलने में सक्षम होना चाहिए। उस कार्य को करने के लिए, आपको अपनी क्वेरी को एक अभिव्यक्ति में बदलना होगा, जिसे एंटिटी फ्रेमवर्क संभाल सकता है।

public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
    string name = this.charityName;
    string referenceNumber = this.referenceNumber;
    return p => 
        (string.IsNullOrEmpty(name) || 
            p.registeredName.ToLower().Contains(name.ToLower()) ||
            p.alias.ToLower().Contains(name.ToLower()) ||
            p.charityId.ToLower().Contains(name.ToLower())) &&
        (string.IsNullOrEmpty(referenceNumber) ||
            p.charityReference.ToLower().Contains(referenceNumber.ToLower()));
}

1
जब संदेह में यह पता चलता है: stackoverflow.com/questions/2352764/…
क्रिस हेस

2
एक निर्मित लौटना Expression<Func<T,type>>यह एक बहुत अच्छा तरीका है।
ट्रैविस जे

आप LINQ एक्सप्रेशन में इसका उपयोग कैसे करेंगे? मैं फिर से प्रयोग करने योग्य जहाँ क्लॉज़ के रूप में ऐसा कुछ करना चाहता हूँ, लेकिन इसे लागू करने के साथ संघर्ष कर रहा हूँ।
जोर्जारथ

4
संपादित करें: कोई बात नहीं, यह होगा:context.Where(IsSatisfied())
जोर्जारथ

मुख्य भाग: "एंटिटी फ्रेमवर्क वास्तव में आपके C # कोड को उसकी क्वेरी के भाग के रूप में नहीं चला सकता है।"
Alper

1

मुझे इस कोड में वही त्रुटि मिली:

 var articulos_en_almacen = xx.IV00102.Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();

यह बिल्कुल त्रुटि थी:

System.NotSupportedException: 'LINQ to Entities विधि' बूलियन एक्स्टिस्ट (System.Predicate`1 [conector_gp.Models.almacenes_por_sucursal)) विधि को मान्यता नहीं देता है, और इस विधि को स्टोर एक्सप्रेशन में अनुवादित नहीं किया जा सकता है। '

मैंने इस तरह हल किया:

var articulos_en_almacen = xx.IV00102.ToList().Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();

मैंने अपनी तालिका से पहले .ToList () जोड़ा , यह इकाई और लाइनक कोड को डिकूप करता है , और मेरी अगली लाइनक अभिव्यक्ति का अनुवाद करने से बचता है

नोट: यह समाधान इष्टतम नहीं है, क्योंकि इकाई फ़िल्टरिंग से बचें, और बस सभी तालिका को मेमोरी में लोड करता है


1
अधिकांश समय यह सबसे आसान समाधान है, लेकिन सभी ऑब्जेक्ट को लोड नहीं करने के लिए मैं आमतौर पर अनाम चयन करता हूं। .ToList () के साथ बस मुझे क्या चाहिए ... xx.Select (x => new {x.Id, x.DateTimeUpateate })। ToList ()। सिलेक्ट करें (x => new {x.Id, DateTimeUpdate = x.DateTimeUpdate.ToString ("dd / MM / yyyy")})
Dijgenes

0

अगर किसी को VB.Net उत्तर की तलाश है (जैसा कि मैं शुरू में था), यहाँ यह है:

Public Function IsSatisfied() As Expression(Of Func(Of Charity, String, String, Boolean))

Return Function(charity, name, referenceNumber) (String.IsNullOrWhiteSpace(name) Or
                                                         charity.registeredName.ToLower().Contains(name.ToLower()) Or
                                                         charity.alias.ToLower().Contains(name.ToLower()) Or
                                                         charity.charityId.ToLower().Contains(name.ToLower())) And
                                                    (String.IsNullOrEmpty(referenceNumber) Or
                                                     charity.charityReference.ToLower().Contains(referenceNumber.ToLower()))
End Function

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.