ऑब्जेक्ट को हटाया नहीं जा सकता क्योंकि यह ObjectStateManager में नहीं मिला था


114

मुझे यह त्रुटि मिल रही है "ऑब्जेक्ट हटाया नहीं जा सकता क्योंकि यह ObjectStateManager में नहीं मिला था।"

मेरा कोड है:

    protected MyEntities sqlEntities;

    public virtual void Delete(TEntity entity)
    {
        System.Type t = typeof(TEntity);
        sqlEntities.DeleteObject(entity);
        sqlEntities.SaveChanges();
    }

5
खेद है कि कोड में यह समस्या थी कि रिकॉर्ड को लाने और हटाने के लिए अलग-अलग डेटाकोटेक्स्ट ऑब्जेक्ट का उपयोग किया गया था।
सामी

मेरे पास इस तरह एक बग var entity = new TEntity() { PK_ID = 23 }; sqlEntities.DeleteObject(entity);था : मैं अपने पीके सेट के साथ एक मॉक इकाई को सही ढंग से बनाने की कोशिश कर रहा था , इस उम्मीद में कि एंटिटी फ्रेमवर्क पीके पर आधारित DeleteObject को कॉल करेगा
सी। टिवाल्ट

जवाबों:


156

इसका मतलब है कि इकाई संलग्न नहीं है (यह उसी संदर्भ उदाहरण द्वारा लोड नहीं किया गया था)। इसे इस्तेमाल करे:

protected MyEntities sqlEntities;

public virtual void Delete(TEntity entity)
{
    sqlEntities.Attach(entity);
    sqlEntities.DeleteObject(entity);
    sqlEntities.SaveChanges();
}

1
धन्यवाद लदिस्लाव इससे मुझे तब मदद मिली जब मेरे पास माता-पिता से बाल डेटा को हटाने के दौरान दो संदर्भ थे - जो कि एक अलग संदर्भ से एक ट्रांसेशनस्कोप के बाहर बुलाया गया था। पैरेंट कॉल को दायरे और उसी संदर्भ में ले जाया गया और मेरी समस्या हल हो गई।
दान रिचारडसन

1
@Ladislav: यदि मैं उपयोग करता हूं। तो, मुझे एक अलग त्रुटि मिल रही है: "IEntityChangeTracker के कई उदाहरणों द्वारा एक इकाई वस्तु को संदर्भित नहीं किया जा सकता है।" क्या इसका मतलब यह है कि डिलीट को रोकने के लिए पहले से ही अन्य ऑब्जेक्ट इंस्टेंस जीवित हैं?
मैट

2
@ मैट: इसका मतलब यह नहीं है कि आपकी वस्तु पहले से ही किसी अन्य संदर्भ से जुड़ी हुई है। इसे एक ही समय में दो से नहीं जोड़ा जा सकता है। आपको इकाई को हटाने के लिए मूल संदर्भ का उपयोग करना चाहिए।
लादिस्लाव मृंका

@ लादिस्लाव: धन्यवाद, जिसने मुझे आगे देखने में मदद की - मुझे यह सवाल मिला जो इसका जवाब देता है कि इसे कैसे संबोधित किया जाए: क्या यह जांचना संभव है कि क्या वस्तु पहले से ही एंटिटी फ्रेमवर्क में डेटा संदर्भ से जुड़ी हुई है? । आप सही कह रहे हैं, यह मेरे मामले में मुद्दा है। त्वरित उत्तर के लिए धन्यवाद!
मैट

अनुस्मारक के लिए धन्यवाद, मैंने इसे केवल एक रिकॉर्ड अपडेट करते समय संलग्न किया था, लेकिन तब नहीं जब मैं एक रिकॉर्ड हटा रहा था।
pinmonkeyiii

60

लदिस्लाव मृंका द्वारा उत्तर पर एक छोटा स्पष्टीकरण (जो स्वीकृत उत्तर होना चाहिए)।

अगर मेरी तरह, आप इस तरह एक प्रारूप में कोड मिल गया है:

using (var context = new MyDataContext())
{
    context.MyTableEntity.Remove(EntytyToRemove);
    var nrOfObjectsChanged = context.SaveChanges();
}

..तो यह आप क्या करना चाहते हैं:

using (var context = new MyDataContext())
{
    // Note: Attatch to the entity:
    context.MyTableEntity.Attach(EntityToRemove);

    context.MyTableEntity.Remove(EntityToRemove);
    var nrOfObjectsChanged = context.SaveChanges();
}

शायद यह स्पष्ट लगता है, लेकिन यह मेरे लिए शुरू में स्पष्ट नहीं था कि इकाई को निर्दिष्ट करने के लिए निर्दिष्ट करना आवश्यक है, और केवल संदर्भ नहीं


1
मैं इस दृष्टिकोण का उपयोग करता हूं और अपवाद प्राप्त करता हूं: "स्टोर अपडेट, इंसर्ट या डिलीट स्टेटमेंट ने अप्रत्याशित संख्या में पंक्तियों को प्रभावित किया (0)। एंटिटीज को लोड होने के बाद संशोधित या हटा दिया गया हो सकता है। ObjectStateManager प्रविष्टियों को रिफ्रेश करें।"
kat1330 18

11

केवल कर्जरतन स्पष्टीकरण पर उचित जवाब देने के लिए:

मैं था:

public Project DeleteProject(int id)
    {
        using (var context = new Context())
        {
            var p = GetProject(id);
            context.Projects.Remove(p);
            context.SaveChanges();
            return p;
        }
    }

समस्या यह है कि मैंने इकाई प्राप्त करने के लिए अपने तरीके (GetProject ()) का उपयोग किया (इसलिए इकाई को लोड करने के लिए किसी अन्य संदर्भ का उपयोग कर):

public Project GetProject(int id)
    {
        using (var context = new Context())
        {
            var project = context.Projects
                .Include(p => p.Reports.Select(q => q.Issues.Select(r => r.Profession)))
                .Include(p => p.Reports.Select(q => q.Issues.Select(r => r.Room)))
                .SingleOrDefault(x => x.Id == id);
            return project;      
        }
    }

एक समाधान भारित इकाई को केजरतन के रूप में संलग्न करने के लिए हो सकता है, दूसरा एक समाधान हो सकता है, एक ही संदर्भ में इकाई को लोड करने के लिए:

public Project DeleteProject(int id)
    {
        using (var context = new Context())
        {
            var p = context.Projects.SingleOrDefault(x => x.Id == id);
            if (p == null)
                return p;

            context.Projects.Remove(p);
            context.SaveChanges();
            return p;
        }
    }

2

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

इसे हल करने के लिए मैंने जो कुछ किया, वह पहले निर्मित संदर्भ को बाकी वर्गों / सेवाओं को भेजना था, जहां डेटाबेस का उपयोग करना था।

उदाहरण के लिए, मैं serviceAइसके कुछ रजिस्टरों को हटाने और कॉल करने serviceBऔर serviceCउनके रजिस्टरों के साथ ऐसा करने जा रहा था ।

मैं तो मेरी रजिस्टरों को हटाना होगा serviceAऔर एक पैरामीटर के रूप पर बनाया संदर्भ पारित serviceAकरने के लिए serviceBऔर serviceC


2

आप इस कोड को लिख सकते हैं:

var x=yourquery.FirstOrDefault(); 

sqlEntities.DeleteObject(x);
sqlEntities.SaveChanges();

1

उपरोक्त किसी भी कार्य में, आप इस समाधान को आजमा सकते हैं:

context.Entry(yourObject).State = System.Data.Entity.EntityState.Deleted; context.SaveChanges();


0

आपको यह सुनिश्चित करना चाहिए कि जिस वस्तु को आप हटाने की कोशिश कर रहे हैं, उस सूची में आपकी वस्तु मौजूद है, आपको निम्नलिखित शर्त रखनी चाहिए

अगर (संदर्भ.आंत.प्रश्न (आपकी वस्तु))

इसे हटा दो।

यदि आपके पास समानता के लिए एक जटिल स्थिति है, तो आपको अपनी स्थिति को समानता के लिए डालने के लिए इकाई वर्ग में समान विधि को ओवरराइड करना चाहिए , एक विस्तार विधि "एंट्री।कंटेन" के लिए सही तरीका पाने के लिए


0

सुनिश्चित करें कि निकालें (इकाई) में पास होने वाला मॉडल डेटाबेस रिकॉर्ड के समान ही है।

कुछ बार ईद या तारीख जैसे कुछ क्षेत्रों के साथ मॉडल को पास करना संभव है। यदि आप फॉर्म के रूप में पोस्ट कर रहे हैं तो उन्हें @ html.Hiddenfor में रखें।

सबसे अच्छा तरीका है कि आईडी को पास करें और फाइंड (आईडी) विधि का उपयोग करके इकाई प्राप्त करें और उसे निकालें (इकाई) को पास करें

आशा है कि यह किसी की मदद करता है।


0

मुझे यह समस्या लगी और इसे हल करना। बस नीचे दिए गए कोड की प्रतिलिपि बनाएँ:

sqlEntities.Attach(entity);
sqlEntities.Remove(entity);
sqlEntities.SaveChanges();

0

मेरे मामले में एक संदर्भ था, लेकिन मुझे 'AsNoTracking' विकल्प के साथ इकाई मिली

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.