एंटिटी फ्रेमवर्क - "टाइप क्लोजर टाइप" ... का निरंतर मान बनाने में असमर्थ "त्रुटि


79

मुझे त्रुटि क्यों मिलती है:

'क्लोजर टाइप' प्रकार का निरंतर मान बनाने में असमर्थ। इस संदर्भ में केवल आदिम प्रकार (उदाहरण के लिए Int32, स्ट्रिंग और गाइड) का समर्थन किया जाता है।

जब मैं निम्नलिखित Linq क्वेरी की गणना करने की कोशिश करता हूं?

IEnumerable<string> searchList = GetSearchList();
using (HREntities entities = new HREntities())
{
   var myList = from person in entities.vSearchPeople
   where upperSearchList.All( (person.FirstName + person.LastName) .Contains).ToList();
}

अद्यतन : यदि मैं समस्या को अलग करने की कोशिश करने के लिए केवल निम्नलिखित प्रयास करता हूं, तो मुझे वही त्रुटि मिलती है:

where upperSearchList.All(arg => arg == arg) 

तो ऐसा लगता है कि समस्या सभी विधि के साथ है, है ना? कोई सुझाव?

जवाबों:


68

ऐसा लगता है कि आप "WHERE ... IN" स्थिति के बराबर करने का प्रयास कर रहे हैं। LINQ से एंटिटीज के लिए उस प्रकार का क्वेरी कैसे करें, उदाहरण के लिए LINQ से एंटिटीज़ का उपयोग करके 'WHERE IN' स्टाइल क्वेश्चन कैसे लिखें, इसकी जाँच करें

इसके अलावा, मुझे लगता है कि इस मामले में त्रुटि संदेश विशेष रूप से अनपेक्षित है, क्योंकि .Containsकोष्ठक द्वारा पालन नहीं किया जाता है, जो कंपाइलर को पूरे विधेय को लंबोदर अभिव्यक्ति के रूप में पहचानने का कारण बनता है।


धन्यवाद डैनियल। प्लेन लाइनक के साथ वही सिंटैक्स ठीक काम करता है। तो, ऐसा लगता है कि समस्या ईएफ के साथ है .net 3.5 SP1 सही है? कोष्ठक के बिना समतुल्य समतुल्य है: जहाँ ऊपरी खोजसूची। सभी (x => (person.FirstName + person.LastName)) .Contains (x))। ToList ();
गस कैवलन्ती

अगर मैं कोशिश करता हूं कि जहां ऊपरी खोजसूची। सभी (arg => arg == arg) उसी त्रुटि को फेंकती है। तो समस्या ऑल मेथड के साथ है ...
गस कैवलन्ती

2
LINQ to Entities एक अद्भुत तकनीक है, लेकिन SQL अनुवाद इंजन सीमित है। मैं आधिकारिक दस्तावेज पर अपने हाथ नहीं डाल सकता, लेकिन मेरे अनुभव में, यदि क्वेरी में केवल मूल गणित और स्ट्रिंग / दिनांक फ़ंक्शन शामिल हैं, तो यह काम नहीं करेगा। क्या आपके पास उस पोस्ट को जांचने का मौका है जिसे मैंने लिंक किया है? यह "WHERE..IN" प्रकार की क्वेरी को एक ऐसे रूप में परिवर्तित करने की प्रक्रिया का वर्णन करता है जो LINQ to Entities के बाद SQL में अनुवाद कर सकता है।
डैनियल प्रैट

आप linq में फ़ंक्शन पॉइंटर्स से संस्थाओं तक का उपयोग नहीं कर सकते। प्रदाता यह नहीं जानता कि इसे एसक्यूएल में बदलने के लिए एक अभिव्यक्ति पेड़ से कैसे खोदना है।
सिनास्टैटिक

@DanielPratt आपका लिंक टूट गया है
मिक

11

मैंने पिछले 6 महीनों को EF 3.5 के साथ इस सीमा से जूझते हुए बिताया है और जब तक मैं दुनिया का सबसे चतुर व्यक्ति नहीं हूं, मुझे पूरा यकीन है कि मेरे पास इस विषय पर पेशकश करने के लिए कुछ उपयोगी है।

"OR स्टाइल" अभिव्यक्तियों के 50 मील ऊंचे पेड़ को उगाने से उत्पन्न SQL एक खराब क्वेरी निष्पादन योजना का परिणाम देगा। मैं कुछ मिलियन पंक्तियों के साथ काम कर रहा हूं और प्रभाव काफी है।

वहाँ एक छोटा सा हैक है जो मुझे एक एसक्यूएल करने के लिए मिला है, जो अगर आप बस आईडी द्वारा संस्थाओं की एक गुच्छा की तलाश में मदद करता है:

private IEnumerable<Entity1> getByIds(IEnumerable<int> ids)
{
    string idList = string.Join(",", ids.ToList().ConvertAll<string>(id => id.ToString()).ToArray());
    return dbContext.Entity1.Where("it.pkIDColumn IN {" + idList + "}");
}

जहाँ pkIDColumn आपकी Entity1 तालिका का प्राथमिक कुंजी आईडी कॉलम नाम है।

लेकिन काट देना!

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

अगर मेरे पास अधिक समय होता है तो मैं इस नेत्रहीन का प्रतिनिधित्व करने की कोशिश करूंगा, लेकिन मैं इस वाक्य का सिर्फ एक पल का अध्ययन नहीं करता: एक व्यक्ति, सरकार और सरकार के तालमेल के साथ एक स्कीमा पर विचार करें। एंड्रयू टापर्ट (व्यक्ति) के दो आईडी कार्ड (GovernmentId) हैं, एक ओरेगन (GovernmentIdType) और एक वाशिंगटन (GovernmentIdType) से है।

अब इससे एक edmx जनरेट करें।

अब कल्पना कीजिए कि आप एक निश्चित आईडी मान वाले सभी लोगों को ढूंढना चाहते हैं, 1234567 कहते हैं।

यह एक एकल डेटाबेस हिट के साथ पूरा किया जा सकता है:

dbContext context = new dbContext();
string idValue = "1234567";
Expression<Func<Person,bool>> expr =
    person => person.GovernmentID.Any(gid => gid.gi_value.Contains(idValue));

IEnumerable<Person> people = context.Person.AsQueryable().Where(expr);

क्या आप यहां उपकुंजी देखते हैं? उत्पन्न चक्र उप-प्रश्नों के बजाय 'जॉइन' का उपयोग करेगा, लेकिन प्रभाव समान है। इन दिनों SQL सर्वर उप-श्रेणियों को वैसे भी कवर के तहत जोड़ देता है, लेकिन वैसे भी ...

इस काम की कुंजी है। अभिव्यक्ति के अंदर कोई भी।


8

मुझे त्रुटि का कारण मिला है (मैं फ्रेमवर्क 4.5 का उपयोग कर रहा हूं)। समस्या यह है, कि EF एक जटिल प्रकार है, जो "Contains" -parameter में पास किया गया है, SQL क्वेरी में अनुवाद नहीं कर सकता। EF SQL क्वेरी में केवल इंट, स्ट्रिंग जैसे सरल प्रकार का उपयोग कर सकते हैं ...

this.GetAll().Where(p => !assignedFunctions.Contains(p))

GetAll एक जटिल प्रकार के साथ वस्तुओं की एक सूची प्रदान करता है (उदाहरण के लिए: "फ़ंक्शन")। इसलिए, मैं अपनी SQL क्वेरी में इस जटिल प्रकार का उदाहरण प्राप्त करने की कोशिश करूंगा, जो स्वाभाविक रूप से काम नहीं कर सकता है!

यदि मैं अपनी सूची से निकाल सकता हूं, तो पैरामीटर जो मेरी खोज के अनुकूल हैं, मैं उपयोग कर सकता हूं:

var idList = assignedFunctions.Select(f => f.FunctionId);
this.GetAll().Where(p => !idList.Contains(p.FunktionId))

अब EF के पास काम करने के लिए जटिल प्रकार "फ़ंक्शन" नहीं है, लेकिन उदाहरण के लिए एक साधारण प्रकार (लंबा)। और यह ठीक काम करता है!


0

मुझे यह त्रुटि संदेश तब मिला जब मेरे सरणी ऑब्जेक्ट का उपयोग किया गया था। सभी फ़ंक्शन शून्य हैं। जब मैंने सरणी ऑब्जेक्ट को इनिशियलाइज़ किया, तो (आपके मामले में ऊपरी खोजकर्ता), त्रुटि चली गई। इस मामले में त्रुटि संदेश भ्रामक था

जहां ऊपरी खोजसूची। सभी (arg => person.someproperty.StartsWith (arg))

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