2016-04-15 11 views
7

जोड़ें मैं ईएफ के साथ एक सी # एएसपी.नेट एमवीसी 5 वेब अनुप्रयोग पर काम कर रहा हूं 5. ईएफ का उपयोग कर मेरे डेटाबेस टेबल का मानचित्रण DbContext कक्षा और .edmx फ़ाइल उत्पन्न करता है। आज, मैं a great article about creating generic DAL classes पढ़ रहा था, लेकिन मैं निम्न वाक्य पर बंद कर दिया:System.Data.EntityState.Add & DbSet के बीच मतभेदों (यदि कोई हो) के बारे में भ्रमित लेख और दस्तावेज़ीकरण।

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

के विपरीत है यही कारण है कि इन सवालों में बताया गया है:

सब से ऊपर सवालों के जवाब में, सभी उपयोगकर्ताओं ने उल्लेख किया कि System.Data.EntityState.Added का उपयोग DbSet.Add का उपयोग करने जैसा ही है। लेकिन मैंने जो लेख पहले उल्लेख किया है, वह बताता है कि System.Data.EntityState.Added का उपयोग ग्राफ के माध्यम से कैस्केड नहीं किया जाएगा।

मेरे परीक्षण के आधार पर, मैंने निष्कर्ष निकाला है कि System.Data.EntityState.AddedDBset.Add मामले में ग्राफ के माध्यम से कैस्केड करेगा। क्या लेख गलत है, या यह मेरा परीक्षण है और क्यू & ए है?

उत्तर

5

ये विधियां वही हैं जिन्हें आप नियमित परीक्षण द्वारा सत्यापित कर सकते हैं, या यदि आप पूरी तरह से सुनिश्चित होना चाहते हैं - ईएफ 6 कोड की कुछ खोज के द्वारा।

  1. DbSet.Add विधि (http://entityframework.codeplex.com/SourceControl/latest#src/EntityFramework/DbSet.cs)

    public virtual TEntity Add(TEntity entity) 
    { 
        Check.NotNull<TEntity>(entity, "entity"); 
        this.GetInternalSetWithCheck("Add").Add((object) entity); 
        return entity; 
    } 
    

यह InternalSet<T>.Add(object) प्रणाली को बुलाती है।

  1. DbEntityEntry<T>.State संपत्ति (http://entityframework.codeplex.com/SourceControl/latest#src/EntityFramework/Infrastructure/DbEntityEntry.cs)

    public EntityState State 
    { 
        get { return _internalEntityEntry.State; } 
        set { _internalEntityEntry.State = value; } 
    } 
    

कहाँ _internalEntityEntryInternalEntityEntry प्रकार का है।

InternalEntityEntry.State संपत्ति (http://entityframework.codeplex.com/SourceControl/latest#src/EntityFramework/Internal/EntityEntries/InternalEntityEntry.cs)

public virtual EntityState State 
    { 
     get { return IsDetached ? EntityState.Detached : _stateEntry.State; } 
     set 
     { 
      if (!IsDetached) 
      { 
       if (_stateEntry.State == EntityState.Modified 
        && value == EntityState.Unchanged) 
       { 
        // Special case modified to unchanged to be "reject changes" even 
        // ChangeState will do "accept changes". This keeps the behavior consistent with 
        // setting modified to false at the property level (once that is supported). 
        CurrentValues.SetValues(OriginalValues); 
       } 
       _stateEntry.ChangeState(value); 
      } 
      else 
      { 
       switch (value) 
       { 
        case EntityState.Added: 
         _internalContext.Set(_entityType).InternalSet.Add(_entity); 
         break; 
        case EntityState.Unchanged: 
         _internalContext.Set(_entityType).InternalSet.Attach(_entity); 
         break; 
        case EntityState.Modified: 
        case EntityState.Deleted: 
         _internalContext.Set(_entityType).InternalSet.Attach(_entity); 
         _stateEntry = _internalContext.GetStateEntry(_entity); 
         Debug.Assert(_stateEntry != null, "_stateEntry should not be null after Attach."); 
         _stateEntry.ChangeState(value); 
         break; 
       } 
      } 
     } 
    } 

आप देखते हैं कि यदि इकाई (अपने मामले) अलग और राज्य जोड़ा गया है - एक ही InternalSet<T>.Add(object) कहा जाता है।

परीक्षण द्वारा

सत्यापन के लिए के रूप में:

using (var ctx = new TestDBEntities()) { 
    // just some entity, details does not matter 
    var code = new Code(); 
    // another entity 
    var error = new Error(); 
    // Code has a collection of Errors 
    code.Errors.Add(error); 
    var codeEntry = ctx.Entry(code); 
    // modify code entry and mark as added 
    codeEntry.State = EntityState.Added; 
    // note we did not do anything with Error 
    var errorEntry = ctx.Entry(error); 
    // but it is marked as Added too, because when marking Code as Added - 
    // navigation properties were also explored and attached, just like when 
    // you do DbSet.Add 
    Debug.Assert(errorEntry.State == EntityState.Added);     
} 
+0

तो आप कह रहे हैं कि EntityState का उपयोग करना। जोड़ा गया और DBset का उपयोग करना। जोड़ें बिल्कुल वही हैं? –

+1

हां, यदि आपकी इकाई किसी संदर्भ द्वारा ट्रैक नहीं की गई है, तो यह विधियां बिल्कुल वही परिणाम करेगी, ठीक उसी परिणाम के साथ, जिसे परीक्षण उदाहरण और स्रोत कोड अन्वेषण द्वारा पुष्टि की जाती है। – Evk

+0

तो मान लें कि इकाई को संदर्भ द्वारा ट्रैक किया जा रहा है, तो क्या वे अलग होंगे? जैसा कि आपने कहा था "अगर आपकी इकाई को ट्रैक नहीं किया गया है ..." –

5

मुझे लगता है कि ब्लॉग के लेखक पता नहीं है। मैं book DbContext के लेखकों को जानता हूं हालांकि (हालांकि व्यक्तिगत रूप से नहीं)। वे ईएफ अंदरूनी जानते हैं। तो जब पेज 80 पर वे लिखते हैं

DbSet.Add कॉलिंग और StateAdded करने के लिए दोनों बिल्कुल भी वही करता है की स्थापना।

मुझे पता है कि मैं क्या कर रहा हूं। इकाई संदर्भ द्वारा ट्रैक नहीं है

है, यह Added राज्य में संदर्भ द्वारा पता लगाया जा रहा शुरू हो जाएंगे: वे बिल्कुल वही बात है, जो है। DbSet.Add और State से Added पर सेट ग्राफ़ ऑपरेशंस- का अर्थ है कि किसी भी अन्य संस्थाओं को संदर्भ द्वारा ट्रैक नहीं किया जा रहा है और रूट इकाई से पहुंच योग्य भी Added के रूप में चिह्नित किया जाएगा।

मुझे यह भी अनुभव है कि यह इस तरह से काम करता है। लेकिन किसी भी संदेह को दूर करने के, एफई के स्रोत कोड में, दोनों DbSet.Add और DbEntityEntry.State (जब Added के लिए सेट) ObjectContext है कि वास्तविक काम करता है में एक ही बिंदु पर पहुंचें:

public virtual void AddObject(string entitySetName, object entity) 

यह एक विशेषता यह है कि डेवलपर्स को भुलाना करने के लिए जारी है कि ईएफ के साथ काम करना शुरू करें, जैसा कि स्टैक ओवरव्लो में बड़ी संख्या में प्रश्नों से स्पष्ट है, "मेरी संस्थाओं को कैसे डुप्लिकेट किया जाता है?" जूली लर्मन ने entire blog लिखा है कि यह क्यों हो सकता है।

इस निरंतर भ्रम ने ईएफ टीम को ईएफ 7 में change this behavior का निर्णय लिया।

शायद आपके द्वारा संदर्भित ब्लॉग के लेखक उन भ्रमित डेवलपर्स में से एक थे।

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