2011-09-05 15 views
5

मुझे लगता है कि मेरे पास आज मेरा बेवकूफ सिर है: मेरे पास लगभग 80,000 पंक्तियों और एक डीबी तालिका (एल 2 ई/ईएफ 4) युक्त एक पीओसीओ प्रकार का एक आईनेमरेबल है जिसमें पंक्तियों का सबसेट होता है जहां "त्रुटि/अंतर बस को अद्यतन करने, त्रुटि में "और फिर पूरा परिणाम सेट अद्यतन करने के लिए प्रयास करता है"आईन्यूमेरेबल <> अपडेट नहीं कर रहा है में ऑब्जेक्ट अपडेट करें?

निम्नलिखित कोड अलग VSACode के हो जाता है (के बारे में 5000 पंक्तियाँ है, लेकिन अक्सर लगभग 150 अलग प्रविष्टियों * मजबूत पाठ * देने के लिए बार-बार) " पंक्तियां जो मेल खाते हैं ... लेकिन यह काम नहीं करती है!

क्या मूर्खता मैंने किया है ?!

var vsaCodes = (from g in db.GLDIFFLs 
    select g.VSACode) 
    .Distinct(); 

foreach (var code in vsaCodes) 
{ 
    var hasDifference = results.Where(r => r.VSACode == code); 
    foreach (var diff in hasDifference) 
    diff.Difference = true; 
} 

var i = results.Count(r => r.Difference == true); 

इस कोड के बाद, मैं = 0

मैं भी कोशिश की है:

foreach (var code in vsaCodes) 
      { 
       results.Where(r => r.VSACode == code).Select(r => { r.Difference = true; return r; }).ToList(); 
      } 

मैं कैसे "परिणाम" केवल मिलान अंतर गुण सेट करने के लिए अद्यतन कर सकते हैं?

उत्तर

10

मान लीजिए results सिर्फ एक प्रश्न है (आपने इसे नहीं दिखाया है), हर बार जब आप इसे फिर से मूल्यांकन करेंगे तो इसका मूल्यांकन किया जाएगा। यदि वह क्वेरी प्रत्येक बार नई ऑब्जेक्ट बनाती है, तो आप अपडेट नहीं देखेंगे। यदि यह वही वस्तुओं के संदर्भ देता है, तो आप करेंगे।

यदि आप को सामग्री क्वेरी परिणाम - उदा। ToList() को अंत में जोड़कर - resultsपर पुनरावृत्ति एक नई क्वेरी जारी नहीं करेगा, और आप अपने परिवर्तन देखेंगे।

+0

मेरा (स्पष्ट रूप से बिल्कुल सही नहीं) समझने के लिए ToList() का उपयोग करने से बचने के लिए था जब तक कि आपको वास्तव में इसकी आवश्यकता नहीं होती ... मुझे लगता है कि यह "वास्तव में इसकी आवश्यकता है" स्थिति है? त्वरित क्यू? क्या सूची को मूर्त रूप देने के लिए कथन/प्रश्नों की मेरी श्रृंखला में टोलिस्ट() को कॉल करना बेहतर है? यदि मैं नहीं करता, तो क्या यह हर बार डीबी से पूछताछ करेगा? – BlueChippy

+0

@ ब्लूशिपी: आमतौर पर आपको जितनी देर हो सके ToList का उपयोग करना चाहिए, ताकि अधिकांश क्वेरी (विशेष रूप से आउटपुट फ़िल्टर करने वाले हिस्सों में) डेटाबेस पर निष्पादित हो। –

+0

धन्यवाद जॉन, अनुमान है कि मैंने इस ToList() को थोड़ा छोटा();) – BlueChippy

2

मैं कुछ समय पहले त्रुटि का एक ही तरह का था। समस्या यह है कि लिनक्स प्रश्न अक्सर स्थगित होते हैं और जब ऐसा प्रतीत होता है कि आप उन्हें बुला रहे हैं तो निष्पादित नहीं किया जाता है। से

कथन "प्रो LINQ भाषा समन्वित क्वेरी सी # में 2010":

"सूचना भले ही हम क्वेरी केवल एक बार, के परिणामों गणन enumerations से प्रत्येक के लिए अलग हैं कहा जाता है कि यह और सबूत है कि क्वेरी स्थगित कर दी गई है। यदि यह नहीं था, तो दोनों गणनाओं के परिणाम समान होंगे। यह लाभ या हानि हो सकता है। यदि आप ऐसा नहीं करना चाहते हैं, तो में से एक का उपयोग करें रूपांतरण ऑपरेटर जो एक आईनेमरेबल वापस नहीं करते हैं ताकि क्वेरी को स्थगित नहीं किया गया है, जैसे ToArray, ToList, ToDictionary, या ToLookup, कैश किए गए परिणाम के साथ एक अलग डेटा संरचना बनाने के लिए जो डेटा स्रोत बदलता है तो नहीं बदलेगा। "

यहाँ आप एक अच्छा यह के उदाहरण के साथ स्पष्टीकरण:

http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx

सादर

0

पार्स शब्द बहुत बारीकी से @ jonskeet के जवाब पर ...

यदि आपकी क्वेरी केवल एक फ़िल्टर है और अंतर्निहित स्रोत ऑब्जेक्ट्स अपडेट हैं, तो क्वेरी का पुनर्मूल्यांकन किया जाएगा और फ़िल्टर ऑब्जेक्ट के आधार पर इन ऑब्जेक्ट को बहिष्कृत किया जा सकता है, इस मामले में आपके क्वेरी परिणाम बाद की गणनाओं पर बदल जाएंगे लेकिन अंतर्निहित वस्तुएं अभी भी अद्यतन किया गया है।

कुंजी एक नए प्रकार के प्रक्षेपण की कमी है जहां तक ​​बदली गई वस्तुओं को अद्यतन और बनाए रखना है।

ToList() इस मुद्दे का सामान्य समाधान है और यदि कोई समस्या है तो यह समस्या हल हो जाएगी लेकिन आपकी क्वेरी फ़िल्टर होने पर चीजें बादल हो जाती हैं लेकिन प्रोजेक्ट नहीं करती हैं। क्वेरी के अपडेट अभी भी मूल स्रोत ऑब्जेक्ट को प्रभावित करते हैं, सब कुछ referencing एक ही ऑब्जेक्ट है।

फिर, शब्दों को पार्स करना लेकिन इन किनारे के मामलों में आप यात्रा कर सकते हैं।

public class Widget 
{ 
    public string Name { get; set; } 
} 

var widgets1 = new[] 
{ 
    new Widget { Name = "Red", }, 
    new Widget { Name = "Green", }, 
    new Widget { Name = "Blue", }, 
    new Widget { Name = "Black", }, 
}; 

// adding ToList() will result in 'static' query result but 
// updates to the objects will still affect the source objects 
var query1 = widgets1 
    .Where(i => i.Name.StartsWith("B")) 
    //.ToList() 
    ; 

foreach (var widget in query1) 
{ 
    widget.Name = "Yellow"; 
} 

// produces no output unless you uncomment out the ToList() above 
// query1 is reevaluated and filters out "yellow" which does not start with "B" 
foreach (var name in query1) 
    Console.WriteLine(name.Name); 

// produces Red, Green, Yellow, Yellow 
// the underlying widgets were updated 
foreach (var name in widgets1) 
    Console.WriteLine(name.Name); 
संबंधित मुद्दे