2012-09-13 37 views
5

मैं डेटा एक्सेस के लिए एंटिटी फ्रेमवर्क 5 (जेनरेटेड पीओसीओ के साथ डेटाबेस-पहले) का उपयोग कर एक एमवीसी 4 वेब एप्लिकेशन बना रहा हूं।मैं एक इकाई फ्रेमवर्क 5 पीओसीओ संरचना को गहराई से दोबारा कैसे जोड़ूं और इसे सहेजूं?

ऐप में, उपयोगकर्ता कई स्क्रीनों के माध्यम से जाता है, दस्तावेज़ बनाने या संपादित करने (जिसे 'केस स्टडी' कहा जाता है)। जब वे अंतिम स्क्रीन पर पहुंचते हैं, तो उनका दस्तावेज़ स्मृति में केसस्टूडी पॉको के रूप में मौजूद होता है, और यह तब तक बढ़िया होता है जब तक कि यह संरचना डेटाबेस में सहेजने का समय न हो।

दस्तावेज़ को संग्रहीत करने के लिए, मैंने कई डेटाबेस तालिकाओं को परिभाषित किया है, जो बदले में व्यापार परत द्वारा उपयोग किए जाने वाले ईएफ पॉको के लिए मानचित्र है, जिसे तब एमवीसी नियंत्रकों द्वारा उपयोग किया जाता है। इस प्रकार, अल्पकालिक डीबी कॉन्टैक्स का उपयोग पीओसीओ को पुनः प्राप्त करने और अनुरोधों के बीच सत्र में स्टोर करने के लिए किया जाता है।

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

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

क्या मुझे यहां कुछ याद आ रही है? क्या यह सर्वोत्तम प्रथाओं के अनुरूप है? क्या पीओसीओ की संरचना संलग्न करने और अपडेट/अपडेट करने के लिए एक और अधिक सुंदर और/या संक्षिप्त तरीका है?

कोड एक मामले का अध्ययन को बचाने के लिए:

public void SaveCaseStudy(CaseStudy caseStudy) 
{ 
    foreach (var s in caseStudy.CaseStudySections) 
    { 
     this.Entities.Sections.Attach(s.Section); 

     if (s.CreatedByRefId == default(Guid)) 
     { 
      s.CreatedByRefId = this.UserRefId; 
      s.CreatedTime = DateTime.Now; 
      this.Entities.CaseStudySections.Add(s); 
     } 
     else 
     { 
      this.Entities.CaseStudySections.Attach(s); 
      var entry = this.Entities.Entry(s); 
      entry.Property(e => e.TextData).IsModified = true; 
      entry.Property(e => e.BinaryData).IsModified = true; 
     } 

     s.LastModifiedByRefId = this.UserRefId; 
     s.LastModifiedTime = DateTime.Now; 
    } 

    foreach (var m in caseStudy.AdditionalMaterials) 
    { 
     if (m.CreatedByRefId == default(Guid)) 
     { 
      m.CreatedByRefId = this.UserRefId; 
      m.CreatedTime = DateTime.Now; 
      this.Entities.AdditionalMaterials.Add(m); 
     } 
     else 
     { 
      this.Entities.AdditionalMaterials.Attach(m); 
     } 

     m.LastModifiedByRefId = this.UserRefId; 
     m.LastModifiedByTime = DateTime.Now; 
    } 

    this.Entities.Layouts.Attach(caseStudy.Layout); 
    this.Entities.Categories.Attach(caseStudy.Category); 

    if (caseStudy.CreatedByRefId != default(Guid)) 
    { 
     this.Entities.CaseStudies.Attach(caseStudy); 
     var entry = this.Entities.Entry(caseStudy); 
     entry.Property(e => e.CaseStudyName).IsModified = true; 
     entry.Property(e => e.CaseStudyTitle).IsModified = true; 
    } 
    else 
    { 
     this.Entities.CaseStudies.Add(caseStudy); 
     caseStudy.CreatedByRefId = this.UserRefId; 
     caseStudy.CreatedTime = DateTime.Now; 
    } 

    caseStudy.LastModifiedByRefId = this.UserRefId; 
    caseStudy.LastModifiedTime = DateTime.Now; 

    if (caseStudy.CaseStudyStatus != (int)CaseStudyStatus.Personalized) 
    { 
     caseStudy.CaseStudyStatus = (int)CaseStudyStatus.PendingApproval; 
    } 

    caseStudy.ApprovedByRefId = null; 
    caseStudy.ApprovedTime = null; 
    this.Entities.SaveChanges(); 

    var existingAdditionalMaterialRefIds = caseStudy.AdditionalMaterials 
     .Select(m => m.AdditionalMaterialRefId) 
     .ToArray(); 

    var additionalMaterialsToRemove = this.Entities.AdditionalMaterials 
     .Where(m => 
      m.CaseStudyRefId == caseStudy.CaseStudyRefId && 
      !existingAdditionalMaterialRefIds.Contains(m.AdditionalMaterialRefId)) 
     .ToArray(); 

    foreach (var additionalMaterialToRemove in additionalMaterialsToRemove) 
    { 
     this.Entities.AdditionalMaterials.Remove(additionalMaterialToRemove); 
    } 

    this.Entities.SaveChanges(); 
} 

उत्तर

3

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

Here थोड़ा पुराना है लेकिन अभी भी विषय के बारे में वैध उत्तर है - संक्षेप में कुछ भी नहीं है क्योंकि मैंने इसे लिखा है, केवल नया डीबीकॉन्टेक्स्ट एपीआई बनाया गया था जो अभी भी पुराने एपीआई के शीर्ष पर बैठता है। इस विषय का सबसे अच्छा विवरण मैंने अब तक देखा है Programming Entity Framework: DbContext पुस्तक में।

2

कैसे बस करने के बारे में:

db.CaseStudies.Attach(caseStudy); 
db.Entry(caseStudy).State = EntityState.Modified; 
db.SaveChange(); 

कि डाटाबेस के लिए अपने मॉडल में सभी परिवर्तनों बचत होगी।

+0

यह दुर्भाग्य से काम नहीं करता है। हमारे मामले में यह एक DbUpdateConcurrencyException उत्पन्न करता है: 'पंक्तियों को अद्यतन, सम्मिलित या हटाएं, पंक्तियों की एक अप्रत्याशित संख्या प्रभावित (0)। इकाइयों को लोड होने के बाद से इकाइयों को संशोधित या हटा दिया गया हो सकता है। ऑब्जेक्टस्टेट प्रबंधक प्रविष्टियों को ताज़ा करें। ऐसा संभव है क्योंकि केसस्टूडी में डेटा ऑब्जेक्ट्स होते हैं, जहां कुछ डेटाबेस में पहले से मौजूद होते हैं (और जाहिर है कि स्पष्ट रूप से पुनः संयोजित होना आवश्यक है), और कुछ नए हैं और उन्हें सम्मिलित करने की आवश्यकता है। –