2013-07-03 6 views
7

efQuery.ToList().Count और efQuery.Count() समान मूल्य का उत्पादन करना चाहिए? एंटिटीफ्रेमवर्क क्वेरी परिणाम बनाम गिनती सूची

यह कैसे संभव है कि efQuery.ToList().Count और efQuery.Count() समान मूल्य नहीं बनाते?

//GetQuery() returns a default IDbSet which is used in EntityFramework 

using (var ds = _provider.DataSource()) 
{ 
    //return GetQuery(ds, filters).Count(); //returns 0??? 
    return GetQuery(ds, filters).ToList().Count; //returns 605 which is correct based on filters 
} 

+1

efQuery IENumerable या IQueryable है? इसके अलावा यदि आप अपना वास्तविक कोड पोस्ट कर सकते हैं जो मदद करेगा। – Maess

+0

efQuery 'IQueryable' है, यह एक क्वेरी है जिसे अभी तक डेटाबेस के विरुद्ध निष्पादित नहीं किया गया है। मैंने कोड जोड़ा है। – ReFocus

उत्तर

1

यहाँ कि efQueryIQueryable है मान लिया जाये कि:

ToList() वास्तव में एक प्रश्न निष्पादित करता है। यदि डेटास्टोर में डेटा में परिवर्तन, ToList() और .Count() पर कॉल के बीच, परिणामस्वरूप एक अलग परिणाम होता है, ToList() कॉल को सूची में दोहराएगा। ToList().Count और .Count() तब मेल खाना चाहिए जब तक स्टोर में डेटा परिणामसेट को दोबारा बदल देता है।

+1

डेटा कॉल के बीच नहीं बदलता है। जब भी मैं कोड चलाता हूं, मैं इस मुद्दे को पुन: पेश कर सकता हूं। दोनों कॉल अलग-अलग परिणाम उत्पन्न करते हैं। यहां तक ​​कि Resharper मुझसे कहता है मैं '.ToList()' मजबूर और '.Count' संपत्ति का उपयोग कर ... – ReFocus

+1

गणना() रिटर्न 0 क्योंकि सूची अब तक तैयार नहीं है के बजाय' .Count() 'विधि का उपयोग करना चाहिए । आप ToList() से पहले क्वेरी वास्तव में निष्पादित होने में क्वेरी को निष्पादित करने के लिए है। यदि आप एक जोड़ते हैं।गिनती() (ToList() के बिना ToList() लाइन के बाद, गणना सही होगी। –

+2

नहीं, 'गणना()' को 'IQueryable' पर एक क्वेरी को मजबूर करना चाहिए - http://stackoverflow.com/questions/890381/how-to-count-rows-within-entityframework-without-loading-contents – ReFocus

5

बस इस में भाग गया। मेरे मामले में मुद्दा यह है कि क्वेरी में एक है। चयन करें() खंड जो आगे के रिश्तों को स्थापित करने का कारण बनता है जो क्वेरी को फ़िल्टरिंग को समाप्त करता है क्योंकि रिश्तेदार आंतरिक शामिल होने से परिणाम में बाधा आती है।

ऐसा प्रतीत होता है कि .Count() क्वेरी का चयन नहीं करता है। क्वेरी का चयन करें।

तो मेरे पास है:

// projection created 
var ordersData = orders.Select(ord => new OrderData() { 
      OrderId = ord.OrderId, 
      ... more simple 1 - 1 order maps 

      // Related values that cause relations in SQL 
      TotalItemsCost = ord.OrderLines.Sum(lin => lin.Qty*lin.Price), 
      CustomerName = ord.Customer.Name, 
}; 


var count = ordersData.Count(); // 207 
var count = ordersData.ToList().Count // 192 

जब मैं SQL कथन की तुलना मुझे लगता है कि गणना() को खोजने के आदेश तालिका जो सभी आदेशों रिटर्न पर एक बहुत ही सरल योग करता है, जबकि दूसरा क्वेरी 100 का एक राक्षस है एसक्यूएल है कि 10 भीतरी मिलती है कि .Select() खंड द्वारा ट्रिगर कर रहे की तर्ज + (वहाँ कुछ और संबंधित मूल्यों/एकत्रित यहाँ दिखाया गया है की तुलना में लिया गया हैं)।

असल में यह इंगित करता है कि .उंट() यह नहीं लेता है। चयन() क्लॉज खाते में जब यह गिनती करता है, तो वे वही रिश्ते जो परिणाम सेट को और बाधित करते हैं, को काउंटर के लिए नहीं निकाल दिया जाता है।()।

मैं स्पष्ट रूप से और साथ ही विधि .Count() कि जो प्रभावी रूप से उन्हें .Count (में बल से उन समग्र परिणाम मूल्यों के कुछ में खींचने के लिए) क्वेरी भाव जोड़कर इस काम करने के लिए सक्षम किया गया है:

var count = ordersData.Count(o=> o.TotalItemsCost != -999 && 
            o.Customer.Name != "[email protected]#"); // 207 

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

मुझे एहसास है कि यह एक कुल हैक है और मुझे उम्मीद है कि एक बेहतर तरीका है, लेकिन इस पल के लिए इसने हमें कम से कम डेटा खींचने के बिना सही मूल्य प्राप्त करने की अनुमति दी है। टोस्टिस्ट() पहले।

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