2014-07-18 5 views
10

उदाहरण संरचनाइकाई की रूपरेखा डुप्लिकेट वस्तु और सभी बच्चे गुण

public class Page 
{ 
    public int PageId { get; set; } 
    public string Prop1 { get; set; } 
    public string Prop2 { get; set; } 
    public virtual List<Section> Sections { get; set; } 
} 

public class Section 
{ 
    public int SectionId { get; set; } 
    public int PageId { get; set; } 
    public virtual Page Page { get; set; } 
    public virtual List<Heading> Headings { get; set; } 
} 

public class Heading 
{ 
    public int HeadingId { get; set; } 
    public int SectionId { get; set; } 
    public virtual Section Section { get; set; } 
} 

यह ध्यान देने योग्य है कि मेरे वास्तविक संरचना इससे अधिक स्तर है, लेकिन यह मैं क्या हासिल करने की कोशिश कर रहा हूँ समझाने के लिए पर्याप्त होना चाहिए लायक है।

तो मैं अपने Page वस्तु लोड मैं तो उस वस्तु क्लोन और Page यानी Prop1 के गुणों के कुछ मामूली परिवर्तन करें, Prop2

Page pageFromDb = getPageMethod(); 
Page clonedPage = pageFromDb.Clone(); 
clonedPage.Prop1 = clonedPage.Prop1 + " Cloned"; 
addPageMethod(clonedPage); //Adds the page to db 

clonedPage संरचना ऊपर के उदाहरण में ठीक है और एक नया Page जोड़ा जाता है डेटाबेस में। हालांकि मुझे विश्वास है क्योंकि बच्चे के ऑब्जेक्ट्स के आईडी सेट हैं और बच्चों के रिश्ते हमेशा एक हैं। मूल ऑब्जेक्ट pageFromDb क्लोन Page के लिए नई Section ऑब्जेक्ट्स बनाने के बजाय नए सभी डाले गए पृष्ठ पर Section.PageId को अपडेट करने के बजाय सभी बच्चों को इकाई फ्रेमवर्क के रूप में खो देगा।

मेरा मानना ​​है कि इसके लिए एक ठीक हो foreach, foreach, आदि के लिए और फिर इकाई की रूपरेखा डालने नए रिकॉर्ड foreach वस्तु बनाने से पहले 0 करने के लिए सभी ईद के सेट होगा। क्या एक इकाई ढांचे के माहौल में ऑब्जेक्ट को क्लोन करने का कोई आसान/बेहतर तरीका है?

+2

क्लोन विधि क्या करती है? क्या यह एक गहरी प्रतिलिपि कर रहा है? क्या आप इसे आईडी फ़ील्ड कॉपी न करने के लिए कह सकते हैं? जब तक आपके संग्रह सही होते हैं, तब तक ईएफ प्रविष्टियों के बाद आपके लिए आईडी बनायेगा। – Tim

+0

@ टिम बस शीर्ष 'पृष्ठ' ऑब्जेक्ट स्तर पर ऑटोमैपर का उपयोग कर रहा है। –

+0

[संभावित फ्रेमवर्क पर क्लोनिंग डेटा] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/2185155/cloning-data-on-entity-framework) –

उत्तर

20

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

यह संदर्भ पर AsNoTracking विधि का उपयोग करके किया जा सकता है।

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

var clone = context.Pages 
    .AsNoTracking() 
    .Including(pages => pages.Sections) 
    .Single(...); 
context.Pages.Add(clone); 
context.SaveChanges(); // creates an entirely new object graph in the database 
+0

'अतिरिक्त जानकारी: रिलेशनशिप के अनुभाग 'अनुभाग_Page_Target' में विरोधाभासी परिवर्तन 'Context.Section_Page' का पता चला है। 'मैं सुझाव दूंगा कि भले ही परिवर्तनों को ट्रैक नहीं किया जा रहा है, फिर भी नेविगेशन गुण अभी भी आबादी वाले हैं। –

+0

हम्म जो पेज क्लोन (AsNoTracking) के रूप में अजीब है, पूरी तरह से संदर्भ से हटा दिया गया है और इसलिए संघर्ष नहीं कर सकता ... क्या आप मूल पृष्ठ को अपने संदर्भ में एक ही कॉल के साथ लोड कर रहे हैं? पृष्ठ लोड करने और क्लोन को सहेजने के अलावा आपके संदर्भ के विरुद्ध कोई अन्य काम चल रहा है? –

+0

महान काम किया! धन्यवाद... –

1

इसे आजमाएं!

public Page CopyPage(int pageID) 
{ 
    using(Context context = new Context()) 
    { 
     context.Configuration.LazyLoadingEnabled = false; 
     Page dbPage = context.Pages.Where(p => p.PageId == pageID).Include(s => s.Sections.Select(s => s.Section)).First(); 
     Page page = dbPage.Clone(); 
     page.PageId = 0; 

     for (int i = 0; i < dbPage .Sections.Count; i++) 
      page.Sections[i] = new Section 
      { 
       SectionId = 0, 
       PageId = 0, 
       Page = null, 
       Headings = dbPage[i].Headings 
      }; 
     return page; 
    } 
} 

public Page Clone() 
    { 
     Object page = this.GetType().InvokeMember("", BindingFlags.CreateInstance, null, this, null); 

     foreach(PropertyInfo propertyInfo in this.GetType().GetProperties()) 
     { 
      if(propertyInfo.CanWrite) 
      { 
       propertyInfo.SetValue(page, propertyInfo.GetValue(this, null), null); 
      } 
     } 

     return page; 
    } 
संबंधित मुद्दे