2009-05-18 14 views
77

"प्रकार 'क्लोजर प्रकार' ... की एक निरंतर मूल्य बनाने में असमर्थ":इकाई की रूपरेखा क्यों मैं त्रुटि क्यों मिलती है त्रुटि

Unable to create a constant value of type 'Closure type'. Only primitive types (for instance Int32, String and Guid) are supported in this context.

जब मैं निम्नलिखित 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) 

तो यह लग रहा है, सही? कोई सुझाव?

उत्तर

67

ऐसा लगता है कि आप एक "कहां ... में" शर्त के बराबर करने के लिए कोशिश कर रहे हैं। LINQ से Entities के साथ उस प्रकार की क्वेरी को कैसे करें, उदाहरण के लिए How to write 'WHERE IN' style queries using LINQ to Entities देखें।

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

+0

धन्यवाद डैनियल। सादा लिंक के साथ एक ही वाक्यविन्यास ठीक काम करता है। तो, ऐसा लगता है कि समस्या .NET 3.5 SP1 में ईएफ के साथ है? कंस्ट्रैसिस के बिना कंटेनर के बराबर है: जहां upperSearchList.All (x => (person.FirstName + person.LastName)। (X))। ToList(); –

+0

यदि मैं कोशिश करता हूं कि upperSearchList.All (arg => arg == arg) यह वही त्रुटि फेंकता है। तो समस्या सभी विधि के साथ है ... –

+2

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

11

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

एसक्यूएल "या शैली" भाव एक गरीब क्वेरी निष्पादन योजना में परिणाम होगा की एक 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 तालिका।

लेकिन पढ़ना जारी रखें!

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

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

अब से एक एडीएमएक्स उत्पन्न करें।

अब कल्पना आप सभी एक निश्चित आईडी मूल्य के लोगों खोजना चाहते हैं, कहते हैं कि 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); 

आप सबक्वेरी दिखाई दे रही है यहाँ? उत्पन्न एसक्यूएल उप-प्रश्नों के बजाय 'जॉइन' का उपयोग करेगा, लेकिन प्रभाव वही है। इन दिनों एसक्यूएल सर्वर सबक्वेरी का अनुकूलन में वैसे भी कवर के तहत मिलती है, लेकिन वैसे भी ...

इस काम के लिए महत्वपूर्ण अभिव्यक्ति के अंदर .Any है।

0

मैं इस त्रुटि संदेश मिला जब मेरे सरणी .सभी समारोह में इस्तेमाल वस्तु अशक्त हो जाने के बाद मैं (अपने मामले में upperSearchList) सरणी वस्तु, प्रारंभ, त्रुटि चला गया है त्रुटि संदेश इस मामले

में गुमराह किया गया था

जहां upperSearchList.All (आर्ग => person.someproperty.StartsWith (आर्ग)))

8

मैं त्रुटि (मैं फ्रेमवर्क 4.5 का उपयोग कर रहा) का कारण मिल गया है। समस्या यह है कि ईएफ एक जटिल प्रकार है, जो "इसमें शामिल है" -परमीटर में पारित होता है, SQL क्वेरी में अनुवाद नहीं कर सकता है। एफई एक 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)) 

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

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