2015-01-12 6 views
6

मेरे पास एक आम समस्या प्रतीत होती है, लेकिन मैं यह नहीं समझ सकता कि वांछित परिणाम कैसे प्राप्त किया जाए। मेरे पास निम्न आरेख में देखी गई नेविगेशन गुणों के साथ एक नेस्टेड इकाई है।इकाई फ्रेमवर्क, थोक सम्मिलन, और संबंध बनाए रखना

enter image description here

नक्शा अंक संग्रह संभवतः किसी दिए गए MapLine के लिए काफी बड़ा हो सकता है और वहाँ काफी MapLayer के लिए MapLines की एक बड़ी संख्या हो सकती है।

यहां सवाल यह है कि एंटीटी फ्रेमवर्क का उपयोग करके डेटाबेस में मैपलेयर ऑब्जेक्ट डालने के लिए सबसे अच्छा तरीका क्या है और अभी भी नेविगेशन गुणों द्वारा परिभाषित रिश्तों को बनाए रखने के लिए सबसे अच्छा तरीका क्या है?

एक मानक इकाई की रूपरेखा कार्यान्वयन

dbContext.MapLayers.Add(mapLayer); 
dbContext.SaveChanges(); 

एक बड़ी स्मृति कील और बहुत गरीब वापसी बार कारण बनता है।

मैं EntityFramework.BulkInsert packagebut it does not honor the relationships of the objects.

यह लगता है जैसे कि यह एक समस्या यह है कि किसी में से पहले समाप्त हो गया है हो सकता है, लेकिन मैं नहीं कर सकते किसी भी संसाधन है कि इस कार्य को पूरा करने के लिए कैसे की व्याख्या खोजने के लिए लग रहे हैं को लागू करने की कोशिश की है।

अद्यतन

मैं रिचर्ड द्वारा दिए गए सुझावों को लागू करने की कोशिश की है, लेकिन मैं समझ नहीं कर रहा हूँ कि कैसे मैं इस तरह के एक मैं का वर्णन किया है के रूप में एक नेस्टेड इकाई के लिए इस बारे में जाना होगा। मैं इस धारणा के तहत दौड़ रहा हूं कि मुझे MapLayer ऑब्जेक्ट, फिर मैपलाइन, फिर डेटाबेस में पीएफ/एफके रिलेशनशिप का सम्मान करने के लिए MapPoints डालने की आवश्यकता है। मैं वर्तमान में निम्नलिखित कोड का प्रयास कर रहा हूं लेकिन यह सही नहीं लगता है।

dbContext.MapLayers.Add(mapLayer); 
dbContext.SaveChanges(); 

List<MapLine> mapLines = new List<MapLine>(); 
List<MapPoint> mapPoints = new List<MapPoint>(); 
foreach (MapLine mapLine in mapLayer.MapLines) 
{ 
    //Update the mapPoints.MapLine properties to reflect the current line object 
    var updatedLines = mapLine.MapPoints.Select(x => { x.MapLine = mapLine; return x; }).ToList(); 

    mapLines.AddRange(updatedLines); 
} 

using (TransactionScope scope = new TransactionScope()) 
{ 
    MyDbContext context = null; 
    try 
    { 
     context = new MyDbContext(); 
     context.Configuration.AutoDetectChangesEnabled = false; 

     int count = 0; 
     foreach (var entityToInsert in mapLines) 
     { 
      ++count; 
      context = AddToContext(context, entityToInsert, count, 100, true); 
     } 

     context.SaveChanges(); 
    } 
    finally 
    { 
     if (context != null) 
      context.Dispose(); 
    } 

    scope.Complete(); 
} 

अद्यतन 2

इसके बाद मैं अंत में छोड़ दिया प्राप्त करने के लिए कई अलग अलग तरीकों से कोशिश कर और सिर्फ एक इकाई के रूप MapLayer डाला जाता है और में कच्चे JSON स्ट्रिंग के रूप MapLines => MapPoints संबंध संग्रहीत MapLayer इकाई पर एक बाइट सरणी (क्योंकि मैं उन संरचनाओं के खिलाफ पूछताछ नहीं कर रहा हूं जो यह मेरे लिए काम करता है)।

जैसा कह रहा है "यह बहुत अच्छा है, लेकिन यह काम करता है"।

मुझे बल्कइन्सर्ट पैकेज के साथ कुछ सफलता मिली और ईएफ के बाहर संबंधों का प्रबंधन किया, लेकिन फिर डेटा को वापस खींचने के लिए ईएफ का उपयोग करने की कोशिश करते समय स्मृति समस्या में भाग गया। ऐसा लगता है कि वर्तमान में, ईएफ बड़े डेटासेट और जटिल संबंधों को कुशलता से संभालने में सक्षम नहीं है।

+0

क्या आप समझा सकते हैं कि आप डेटा के बाद डेटा के साथ क्या कर रहे हैं? मुझे दिलचस्पी है, अगर आपके डेटा के लिए केवल एक साधारण बाइनरी प्रारूप का उपयोग करना बेहतर नहीं है। –

उत्तर

14

मुझे विशाल संदर्भ बचाने के साथ बुरा अनुभव था।1000 पंक्तियों द्वारा 100 पंक्तियों द्वारा पुनरावृत्तियों में सहेजने के बारे में उन सभी सिफारिशों, फिर संदर्भ या समाशोधन सूची का निपटान करना और वस्तुओं को अलग करना, सब कुछ आदि को शून्य देना आदि - यह सब बकवास है। हमें कई तालिकाओं में दैनिक लाखों पंक्तियों को सम्मिलित करने की आवश्यकता थी। निश्चित रूप से इन शर्तों में इकाई का उपयोग नहीं करना चाहिए। जब आप आगे बढ़ते हैं तो आप मेमोरी लीक के साथ लड़ेंगे और सम्मिलन गति में कमी करेंगे।

हमारा पहला सुधार संग्रहीत प्रक्रियाओं को बना रहा था और उन्हें मॉडल में जोड़ रहा था। यह Context.SaveChanges() से 100 गुना तेज है, और समय के साथ गति में कोई कमी नहीं है, कोई कमी नहीं है।

लेकिन यह हमारे लिए पर्याप्त नहीं था और हमने SqlBulkCopy का उपयोग करने का निर्णय लिया। यह बहुत तेज़ है। संग्रहीत प्रक्रियाओं का उपयोग करते हुए 1000 गुना तेजी से।

तो मेरा सुझाव होगा: यदि आपके पास डालने के लिए कई पंक्तियां हैं लेकिन गणना 50000 पंक्तियों की तरह है, संग्रहित प्रक्रियाओं का उपयोग करें, मॉडल में आयात किया गया है; यदि आपके पास सैकड़ों हजार पंक्तियां हैं, तो जाएं और SqlBulkCopy आज़माएं। आप संदर्भ के साथ DbTransaction का उपयोग करते हैं और साथ ही है कि लेनदेन का उपयोग कर, आप थोक डालने के लिए प्रबंधन कर सकते हैं

EntityConnection ec = (EntityConnection)Context.Connection; 
SqlConnection sc = (SqlConnection)ec.StoreConnection; 

var copy = new SqlBulkCopy(sc, SqlBulkCopyOptions.CheckConstraints | SqlBulkCopyOptions.Default , null); 

copy.DestinationTableName = "TableName"; 
copy.ColumnMappings.Add("SourceColumn", "DBColumn"); 
copy.WriteToServer(dataTable); 
copy.Close(); 

, लेकिन यह कुछ हैक्स की जरूरत है:

यहाँ कुछ कोड है।

+0

"मुझे विशाल संदर्भ बचाने के साथ बुरा अनुभव था। 1000 पंक्तियों द्वारा 100 पंक्तियों द्वारा पुनरावृत्तियों में सहेजने के बारे में उन सभी सिफारिशों, फिर संदर्भ या समाशोधन सूची का निपटान करना और वस्तुओं को अलग करना, सब कुछ आदि को शून्य देना आदि - यह सब बकवास है।" - इस बिंदु तक पढ़ें और +1 पहले से ही –

+0

लेकिन संबंध मुद्दे के बारे में क्या है? वह उसे कैसे हल करेगा? –

+1

@eranotzap, यदि आप थोक डालने के दौरान रिश्तेशिप का मतलब रखते हैं, तो हमने केवल मूल तालिका में 2 अतिरिक्त कॉलम जोड़े और कोड में इसे भर दिया। 1 भाग के लिए है PortionID कहते हैं, दूसरे संबंध के लिए संबंध संबंध कहते हैं। थोक सम्मिलन के बाद हम भाग से डेटा का चयन करते हैं और हम आईडी और रिलेशनशिप का चयन करते हैं। तो अब मेरे पास संबंध हैं और रिलेशनशिप की तुलना में बाल अभिलेखों और डीबी से आईडी निर्दिष्ट करने के लिए उपयुक्त आईडी असाइन करें। फिर मैं बच्चों के लिए एक और bulkinsert करते हैं। –

6

थोक सम्मिलन इकाई फ्रेमवर्क का उपयोग करके डेटा को कुशलतापूर्वक जोड़ने का एकमात्र तरीका नहीं है - this answer में कई विकल्प विस्तृत हैं। आप वहां सुझाए गए ऑप्टिमाइज़ेशन का उपयोग कर सकते हैं (परिवर्तन ट्रैकिंग अक्षम करना) तो आप केवल सामान्य चीज़ों को जोड़ सकते हैं।

ध्यान दें कि जैसे ही आप एक साथ कई आइटम जोड़ रहे हैं, आपको मेमोरी रिसाव और मंदी को रोकने के लिए आपको अपने संदर्भ को बार-बार फिर से बनाना होगा।

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