ASP.NET MVC - 'MODELNAME' प्रकार की एक इकाई संलग्न करना विफल रहा क्योंकि उसी प्रकार की एक अन्य इकाई में पहले से ही समान प्राथमिक सेवा मान है


121

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

कृपया नीचे मेरा कोड खोजें (मॉडल के नाम को पढ़ने में आसान बनाने के लिए बदल दिया गया है)

नमूना

// Wrapper classes
        public class AViewModel
        {
            public A a { get; set; }
            public List<B> b { get; set; }
            public C c { get; set; }
        }   

नियंत्रक

        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            if (!canUserAccessA(id.Value))
                return new HttpStatusCodeResult(HttpStatusCode.Forbidden);

            var aViewModel = new AViewModel();
            aViewModel.A = db.As.Find(id);

            if (aViewModel.Receipt == null)
            {
                return HttpNotFound();
            }

            aViewModel.b = db.Bs.Where(x => x.aID == id.Value).ToList();
            aViewModel.Vendor = db.Cs.Where(x => x.cID == aViewModel.a.cID).FirstOrDefault();

            return View(aViewModel);
        }

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(AViewModel aViewModel)
        {
            if (!canUserAccessA(aViewModel.a.aID) || aViewModel.a.UserID != WebSecurity.GetUserId(User.Identity.Name))
                return new HttpStatusCodeResult(HttpStatusCode.Forbidden);

            if (ModelState.IsValid)
            {
                db.Entry(aViewModel.a).State = EntityState.Modified; //THIS IS WHERE THE ERROR IS BEING THROWN
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(aViewModel);
        }

जैसा कि ऊपर लाइन में दिखाया गया है

db.Entry(aViewModel.a).State = EntityState.Modified;

अपवाद फेंकता है:

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

क्या किसी को मेरे कोड में कुछ भी गलत दिखता है या यह समझ में आता है कि किसी मॉडल को संपादित करने के दौरान वह किन परिस्थितियों में ऐसी त्रुटि करेगा?


क्या आपने अपनी इकाई को स्थापित करने से पहले संलग्न करने की कोशिश की है EntityState? जैसा कि आपकी इकाई पोस्ट अनुरोध से आती है, इसे वर्तमान संदर्भ द्वारा ट्रैक नहीं किया जाना चाहिए, मुझे लगता है कि यह मानता है कि आप मौजूदा आईडी के साथ एक आइटम जोड़ने की कोशिश करते हैं
रेदा मेटर

मैंने इसे एक कोशिश की है और परिणाम बिल्कुल समान है :( किसी कारण से संदर्भ सोचता है कि Im एक नया आइटम बना रहा है, लेकिन Im अभी मौजूदा एक को अद्यतन कर रहा है ...
क्रिस Ciszak

मैं त्रुटि को फेंकने से पहले 'a' की स्थिति की जांच करता हूं और इस ऑब्जेक्ट की स्थिति 'अलग' है, लेकिन db.As.Attach (aViewModel.a) को कॉल करना वास्तव में एक ही संदेश फेंकता है? कोई विचार?
क्रिस सिज़्ज़क

5
मैंने अभी आपका अपडेट देखा, आपने अपने संदर्भ को जीवन भर के दायरे में कैसे सेट किया? क्या यह अनुरोध के अनुसार है? यदि dbआपके दो कार्यों के बीच उदाहरण समान है, तो यह आपकी समस्या की व्याख्या कर सकता है, क्योंकि आपका आइटम GET विधि द्वारा लोड किया गया है (तब संदर्भ द्वारा ट्रैक किया गया है), और यह आपके POST पद्धति में किसी को पहचान नहीं सकता है क्योंकि इकाई पहले प्राप्त हुई थी ।
राडे मटर

1
क्या canUserAccessA()इकाई को सीधे लोड करता है या किसी अन्य एंटिटी के संबंध के रूप में?
कोडकस्टर

जवाबों:


154

समस्या सुलझ गयी!

Attachविधि संभावित रूप से किसी की मदद कर सकती है लेकिन यह इस स्थिति में मदद नहीं करेगा क्योंकि एडिट जीईटी कंट्रोलर फ़ंक्शन में लोड किए जाने के दौरान दस्तावेज़ को पहले से ही ट्रैक किया जा रहा था। अटैच ठीक उसी त्रुटि को फेंक देगा।

मेरे द्वारा यहां जारी की गई समस्या फ़ंक्शन के कारण हुई थी canUserAccessA()जो ऑब्जेक्ट की स्थिति को अपडेट करने से पहले ए इकाई को लोड करती है। यह ट्रैक की गई इकाई को खराब कर रहा था और यह एक वस्तु की स्थिति को बदल रहा था Detached

समाधान यह था canUserAccessA()कि मैं जिस वस्तु को लोड कर रहा था, उसे ट्रैक नहीं किया जाएगा। AsNoTracking()संदर्भ को उद्धृत करते हुए फ़ंक्शन को बुलाया जाना चाहिए।

// User -> Receipt validation
private bool canUserAccessA(int aID)
{
    int userID = WebSecurity.GetUserId(User.Identity.Name);
    int aFound = db.Model.AsNoTracking().Where(x => x.aID == aID && x.UserID==userID).Count();

    return (aFound > 0); //if aFound > 0, then return true, else return false.
}

किसी कारण से मैं उपयोग नहीं कर सका .Find(aID), AsNoTracking()लेकिन यह वास्तव में कोई फर्क नहीं पड़ता क्योंकि मैं क्वेरी को बदलकर समान हासिल कर सकता था।

आशा है कि यह इसी तरह की समस्या के साथ किसी को भी मदद करेगा!


10
थोड़ा नट और अधिक प्रदर्शन करने वाला: if (db.As.AsNoTracking) ()। कोई भी (x => x.aID == aID && x.UserID == userID))
ब्रेंट

11
नोट: आपको using System.Data.Entity;उपयोग करने की आवश्यकता है AsNoTracking()
मैक्सिम

मेरे मामले में केवल इकाई आईडी को छोड़कर क्षेत्रों को अपडेट करने के लिए ठीक काम किया गया है: var एंटिटी = संदर्भ ।ind (यूनिट_आईडी); Unit.someProperty = newValue; सन्दर्भ.संपादित करें (एंटिटी) .प्रतिष्ठा (x => x.someProperty) .IsModified = true; context.SaveChanges ();
एंटोन लिहिन

3
बड़े पैमाने पर मदद। मैंने अपने FirstOrDefault () से पहले .AsNoTracking () जोड़ा और यह काम कर गया।
coggicc

109

दिलचस्प बात यह है:

_dbContext.Set<T>().AddOrUpdate(entityToBeUpdatedWithId);

या यदि आप अभी भी सामान्य नहीं हैं:

_dbContext.Set<UserEntity>().AddOrUpdate(entityToBeUpdatedWithId);

लगता है मेरी समस्या को सुचारू रूप से हल कर दिया है।


1
कमाल है, कि मेरे परिदृश्य में सही काम किया है जहाँ मैं एक डिस्कनेक्टेड ऐप में कस्टम जॉइन टेबल के साथ कई में रिकॉर्ड अपडेट करने की आवश्यकता थी। यहां तक ​​कि डेटाबेस से निकाले गए निकाय के साथ, मुझे संदर्भात्मक त्रुटियां मिल रही थीं, आदि मैं "संदर्भ.इंट्री (स्कोर) ।State = System.Data.Entity.EntityState.Modified;" का उपयोग कर रहा था। लेकिन यह अंत में काम किया! धन्यवाद!!
फायरस्केप

5
यह काम। संलग्न करने और उपयोग न करने के बारे में अन्य सभी सुझाव विफल हो गए क्योंकि मैं पहले से ही noTracking कर रहा था। समाधान के लिए धन्यवाद।
16

3
यह मेरे लिए काम की एक ही इकाई के भीतर माता-पिता और बाल संस्थाओं को अद्यतन करने के लिए काम करता है । बहुत धन्यवाद
इयान

55
किसी के लिए भी, नामस्थान AddOrUpdateमें एक विस्तार विधि है System.Data.Entity.Migrations
निक

1
@Artyomska दुर्भाग्य से मुझे नहीं पता।
गनयूस

15

ऐसा लगता है कि जिस इकाई को आप संशोधित करने का प्रयास कर रहे हैं, उसे सही तरीके से ट्रैक नहीं किया जा रहा है और इसलिए इसे संपादित के रूप में पहचाना नहीं गया है, बल्कि इसके बजाय जोड़ा गया है।

सीधे राज्य स्थापित करने के बजाय, निम्नलिखित करने का प्रयास करें:

//db.Entry(aViewModel.a).State = EntityState.Modified;
db.As.Attach(aViewModel.a); 
db.SaveChanges();

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

अपडेट करें:

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

यहाँ विस्तृत विवरण दिया गया है:

http://www.stevefenton.co.uk/Content/Blog/Date/201303/Blog/Why-You-Never-Expose-Your-Domain-Model-As-Your-MVC-Model/


3
हाय Kaspars, इनपुट के लिए धन्यवाद। अटैच विधि मेरे प्रश्न में उल्लिखित त्रुटियों के समान है। समस्या यह है कि canUserAccessA () फ़ंक्शन लोड इकाई के साथ-साथ CodeCaster ऊपर देखा गया है। लेकिन यह कहते हुए कि मुझे आपके सुझाव में बहुत दिलचस्पी है, सुरक्षा के संबंध में। क्या आप सुझाव दे सकते हैं कि इस तरह के व्यवहार को रोकने के लिए मुझे क्या करना चाहिए?
क्रिस सिस्ज़क

सुरक्षा भेद्यता को रोकने के तरीके के बारे में अतिरिक्त जानकारी के साथ मेरे उत्तर को अपडेट किया।
कास्पर्स ओज़ोल्स

13

इसे इस्तेमाल करे:

var local = yourDbContext.Set<YourModel>()
                         .Local
                         .FirstOrDefault(f => f.Id == yourModel.Id);
if (local != null)
{
  yourDbContext.Entry(local).State = EntityState.Detached;
}
yourDbContext.Entry(applicationModel).State = EntityState.Modified;

11

मेरे लिए स्थानीय प्रति समस्या का स्रोत थी। यह हल हो गया

var local = context.Set<Contact>().Local.FirstOrDefault(c => c.ContactId == contact.ContactId);
                if (local != null)
                {
                    context.Entry(local).State = EntityState.Detached;
                }

10

मेरा मामला यह था कि मुझे अपने MVC ऐप से EF के संदर्भ में सीधी पहुँच नहीं थी।

यदि आप इकाई दृढ़ता के लिए किसी प्रकार के भंडार का उपयोग कर रहे हैं तो यह स्पष्ट रूप से भरी हुई इकाई को अलग करने और फिर संशोधित करने के लिए बाइंडेड एंटिटीस्टेट सेट करने के लिए उपयुक्त हो सकता है।

नमूना (सार) कोड:

MVC

public ActionResult(A a)
{
  A aa = repo.Find(...);
  // some logic
  repo.Detach(aa);
  repo.Update(a);
}

कोष

void Update(A a)
{
   context.Entry(a).EntityState = EntityState.Modified;
   context.SaveChanges();
}

void Detach(A a)
{
   context.Entry(a).EntityState = EntityState.Detached;
}

यह मेरे लिए काम किया, हालांकि मैं संदर्भ इकाई राज्यों को संदर्भित करने के लिए भंडार का उपयोग करने से परेशान नहीं हुआ।
एकर्ट

3

मैंने सोचा था कि मैं इस पर अपना अनुभव साझा करूँगा, भले ही मैं जल्द ही इसे साकार न करने के लिए थोड़ा मूर्खतापूर्ण महसूस कर रहा हूं।

मैं अपने नियंत्रकों में इंजेक्शन किए गए रेपो उदाहरणों के साथ रिपॉजिटरी पैटर्न का उपयोग कर रहा हूं। कंक्रीट रिपॉजिटरी मेरे मॉडल कॉन्टेक्स्ट (DbContext) को तुरंत भेजती है जो रिपॉजिटरी के जीवनकाल तक रहता है, जो हैIDisposable नियंत्रक द्वारा निपटाया जाता है।

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

यह फिक्स बस रिपॉजिटरी को नए-अप के संदर्भ में बदलने के लिए था, एक बार कंस्ट्रक्टर में निम्न विधियों को रखने के लिए:

    private DbContext GetDbContext()
    {
        return this.GetDbContext(false);
    }


    protected virtual DbContext GetDbContext(bool canUseCachedContext)
    {
        if (_dbContext != null)
        {
            if (canUseCachedContext)
            {
                return _dbContext;
            }
            else
            {
                _dbContext.Dispose();
            }
        }

        _dbContext = new ModelContext();

        return _dbContext;
    }

    #region IDisposable Members

    public void Dispose()
    {
        this.Dispose(true);
    }

    protected virtual void Dispose(bool isDisposing)
    {
        if (!_isDisposed)
        {
            if (isDisposing)
            {
                // Clear down managed resources.

                if (_dbContext != null)
                    _dbContext.Dispose();
            }

            _isDisposed = true;
        }
    }

    #endregion

यह रिपॉजिटरी विधियों को कॉल करके प्रत्येक उपयोग पर उनके संदर्भ उदाहरण को फिर से नया करने की अनुमति देता है GetDbContext, या यदि वे ऐसा सच चाहते हैं तो पिछले उदाहरण का उपयोग करें।


2

मैंने इस उत्तर को केवल इसलिए जोड़ा है क्योंकि समस्या को अधिक जटिल डेटा पैटर्न के आधार पर समझाया गया है और मुझे यहां समझना मुश्किल है।

मैंने काफी सरल अनुप्रयोग बनाया। यह त्रुटि पोस्ट POST कार्रवाई के अंदर हुई। कार्रवाई ने ViewModel को एक इनपुट पैरामीटर के रूप में स्वीकार किया। रिकॉर्ड सहेजने से पहले ViewModel का उपयोग करने का कारण कुछ गणना करना था।

एक बार कार्रवाई जैसे सत्यापन के माध्यम से पारित कर दिया if(ModelState.IsValid) , , मेरी गलती ViewModel से मूल्यों को पूरी तरह से नए उदाहरण में प्रोजेक्ट करने की थी। मैंने सोचा कि मुझे अद्यतन डेटा संग्रहीत करने के लिए एक नया उदाहरण बनाना होगा और फिर ऐसे उदाहरण को सहेजना होगा।

मुझे बाद में पता चला कि मुझे डेटाबेस से रिकॉर्ड पढ़ना था:

Student student = db.Students.Find(s => s.StudentID == ViewModel.StudentID);

और इस वस्तु को अद्यतन किया। अब सब कुछ काम करता है।


2

मुझे स्थानीय संस्करण के साथ यह समस्या थी और मैं इसे इस तरह से अलग कर रहा हूं:

if (ModelState.IsValid)
{
    var old = db.Channel.Find(channel.Id);
    if (Request.Files.Count > 0)
    {
        HttpPostedFileBase objFiles = Request.Files[0];
        using (var binaryReader = new BinaryReader(objFiles.InputStream))
        {
            channel.GateImage = binaryReader.ReadBytes(objFiles.ContentLength);
        }

    }
    else
        channel.GateImage = old.GateImage;
    var cat = db.Category.Find(CatID);
    if (cat != null)
        channel.Category = cat;
    db.Entry(old).State = EntityState.Detached; // just added this line
    db.Entry(channel).State = EntityState.Modified;
    await db.SaveChangesAsync();
    return RedirectToAction("Index");
}
return View(channel);

एक ही कुंजी के साथ लोड की गई वस्तुओं के कारण समस्या, इसलिए पहले हम उस ऑब्जेक्ट को अलग कर देंगे और एक ही कुंजी के साथ दो ऑब्जेक्ट के बीच संघर्ष से बचने के लिए अपडेट करना


@Artjom B एक ही कुंजी के साथ लोड की गई वस्तुओं की समस्या का कारण बनता है, इसलिए पहले हम उस वस्तु को अलग कर लेंगे और दो ऑब्जेक्ट्स के बीच एक ही कुंजी के साथ टकराव से बचने के लिए
अपडेटिंग करेंगे

2

2-3 दिनों तक जांच के बाद मुझे एक समान मुद्दा मिला, ".AnNoTracking" को हटा दिया जाना चाहिए क्योंकि EF परिवर्तनों को ट्रैक नहीं करता है और मानता है कि जब तक कोई ऑब्जेक्ट संलग्न नहीं होता है तब तक कोई बदलाव नहीं होता है। इसके अलावा, अगर हम उपयोग नहीं करते हैं। कोई सूचना नहीं है, तो EF स्वचालित रूप से जानता है कि कौन सी वस्तु को सहेजना / अद्यतन करना है इसलिए Attach / जोड़ा का उपयोग करने की कोई आवश्यकता नहीं है।


2

उपयोग करें AsNoTracking()जहां आप अपनी क्वेरी प्राप्त कर रहे हैं।

  var result = dbcontext.YourModel.AsNoTracking().Where(x => x.aID == aID && x.UserID==userID).Count();

2

मुझे यह त्रुटि आई

  • एक एकल नियंत्रक में दो विधियां, ए और बी, दोनों ने एक ही उदाहरण के एक ApplicationDbContext का उपयोग किया, और
  • विधि A जिसे विधि B कहा जाता है
    private ApplicationDbContext db;
    // api methods
    public JsonResult methodA(string id){
        Resource resource = db.Resources.Find(id);
        db.Entry(resource).State = EntityState.Modified;
        db.SaveChanges();
        return methodB()
    }

    public JsonResult methodB(string id){
        Resource resource = db.Resources.Find(id);
        db.Entry(resource).State = EntityState.Modified;
        db.SaveChanges();
        return new JsonResult();
    }

मैंने एक उपयोग कथन के लिए विधि B को बदल दिया और केवल स्थानीय db2 पर भरोसा किया । उपरांत:

    private ApplicationDbContext db;    
    // api methods    
    public JsonResult methodA(string id){
        Resource resource = db.Resources.Find(id);
        db.Entry(resource).State = EntityState.Modified;
        db.SaveChanges();
        return methodB()
    }

    public JsonResult methodB(string id){
        using (var db2 = new ApplicationDbContext())
        {
            Resource resource = db2.Resources.Find(id);
            db2.Entry(resource).State = EntityState.Modified;
            db2.SaveChanges();
        }
        return new JsonResult();
    }

1

ल्यूक पुप्लेट जो कह रहा है, उसके समान है, समस्या आपके संदर्भ को ठीक से निपटाने या नहीं बनाने के कारण हो सकती है।

मेरे मामले में, मेरे पास एक वर्ग था जिसने एक संदर्भ स्वीकार किया ContextService:

public class ContextService : IDisposable
{
    private Context _context;

    public void Dispose()
    {
        _context.Dispose();
    }
    public ContextService(Context context)
    {
        _context = context;
    }
//... do stuff with the context

मेरी संदर्भ सेवा में एक फंक्शन था जो एक इंस्टेंटिएटेड ऑब्जेक्ट ऑब्जेक्ट का उपयोग करके एक इकाई को अपडेट करता है:

        public void UpdateEntity(MyEntity myEntity, ICollection<int> ids)
        {
            var item = _context.Entry(myEntity);
            item.State = EntityState.Modified;
            item.Collection(x => x.RelatedEntities).Load();
            myEntity.RelatedEntities.Clear();
            foreach (var id in ids)
            {
                myEntity.RelatedEntities.Add(_context.RelatedEntities.Find(id));
            }
            _context.SaveChanges();
        }

यह सब ठीक था, मेरा नियंत्रक जहां मैंने सेवा शुरू की थी वह समस्या थी। मेरा नियंत्रक मूल रूप से इस तरह दिखता था:

    private static NotificationService _service = 
        new NotificationService(new NotificationContext());
    public void Dispose()
    {
    }

मैंने इसे इसे बदल दिया और त्रुटि दूर हो गई:

    private static NotificationService _service;
    public TemplateController()
    {
        _service = new NotificationService(new NotificationContext());
    }
    public void Dispose()
    {
        _service.Dispose();
    }

1

यह समस्या दौरान देखा जा सकता है ViewModelके लिए EntityModelमानचित्रण (का उपयोग करके AutoMapperऔर शामिल करने के लिए कोशिश कर रहा है, आदि) context.Entry().Stateऔर context.SaveChanges()जैसा कि नीचे दिखाया समस्या का समाधान होगा इस तरह के एक ब्लॉक का उपयोग। कृपया ध्यान रखें कि context.SaveChanges()विधि का उपयोग करने के बजाय दो बार उपयोग किया जाता है if-blockक्योंकि यह ब्लॉक का उपयोग करने में होना चाहिए।

public void Save(YourEntity entity)
{
    if (entity.Id == 0)
    {
        context.YourEntity.Add(entity);
        context.SaveChanges();
    }
    else
    {
        using (var context = new YourDbContext())
        {
            context.Entry(entity).State = EntityState.Modified;
            context.SaveChanges(); //Must be in using block
        }
    }            
}

उम्मीद है की यह मदद करेगा...


1

यहाँ मैंने ऐसे ही मामले में क्या किया।

सिटैचुएशन का अर्थ है कि एक ही इकाई पहले से ही संदर्भ में मौजूद है। निम्नलिखित में मदद कर सकता है

यदि इकाई संदर्भ में है, तो ChangeTracker से पहले जांचें

var trackedEntries=GetContext().ChangeTracker.Entries<YourEntityType>().ToList();

var isAlreadyTracked =
                    trackedEntries.Any(trackedItem => trackedItem.Entity.Id ==myEntityToSave.Id);

अगर यह मौजूद है

  if (isAlreadyTracked)
            {
                myEntityToSave= trackedEntries.First(trackedItem => trackedItem.Entity.Id == myEntityToSave.Id).Entity;
            } 

else
{
//Attach or Modify depending on your needs
}

1

मैं राज्य को अद्यतन करके समस्या को ठीक करने का प्रयास करता हूं। जब आप एक ही रिकॉर्ड sate पर खोज या किसी अन्य क्वेरी ऑपरेशन को संशोधित करने के साथ अद्यतन करते हैं, तो हमें अलग करने के लिए स्थिति सेट करने की आवश्यकता होती है, तब आप अपने अद्यतन को बदल सकते हैं

     ActivityEntity activity = new ActivityEntity();
      activity.name="vv";
    activity.ID = 22 ; //sample id
   var savedActivity = context.Activities.Find(22);

            if (savedActivity!=null)
            {
                context.Entry(savedActivity).State = EntityState.Detached;
                context.SaveChanges();

                activity.age= savedActivity.age;
                activity.marks= savedActivity.marks; 

                context.Entry(activity).State = EntityState.Modified;
                context.SaveChanges();
                return activity.ID;
            }

1

मैं "ब्लॉक" का उपयोग करके इस समस्या को हल करता हूं

using (SqlConnection conn = new SqlConnection(connectionString))

    {

       // stuff to do with data base
    }

    // or if you are using entity framework 
    using (DataBaseEntity data = new DataBaseEntity)
{

    }

यहाँ मुझे आइडिया मिलता है https://social.msdn.microsoft.com/Forums/sqlserver/es-ES/b4b350ba-b0d5-464d-8656-8c117b55b2af/problema-al-modificar-en-entity-framework?forum = vcses स्पेनिश में है (दूसरे उत्तर के लिए देखें)


बस सावधान रहना होगा और केवल डेटाबेस Conexion के 1 उदाहरण का उपयोग करें, विशेष रूप से आप इकाई की रूपरेखा उपयोग कर रहे हैं अगर आप यह मत करो आप त्रुटि इकाई की रूपरेखा एक इकाई वस्तु IEntityChangeTracker के कई उदाहरण द्वारा संदर्भित नहीं कर सकते हो जाएगा जा
Suzume

1

आप की तरह जोड़ा विधि का उपयोग कर सकते हैं;

_dbContext.Entry(modelclassname).State = EntityState.Added;

लेकिन कई मामलों में अगर आप उस समय एक से अधिक मॉडल का उपयोग करना चाहते हैं तो यह काम नहीं करेगा क्योंकि इकाई पहले से ही किसी अन्य इकाई से जुड़ी हुई है। तो, उस समय आप ADDOrUpdate Entity प्रवासन विधि का उपयोग कर सकते हैं जो बस एक से दूसरे में ऑब्जेक्ट को माइग्रेट करता है और परिणामस्वरूप आपको कोई त्रुटि नहीं मिलेगी।

_dbContext.Set<modelclassname>().AddOrUpdate(yourmodel);

0

सभी राज्य साफ़ करें

dbContextGlobalERP.ChangeTracker.Entries ()। जहाँ (e => e.Entity! = null) .ToList ()। ForEach (e => e.Stel = EntityState.Detached);

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