এএসপি.নেট এমভিসি - '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;

ব্যতিক্রম নিক্ষেপ:

'A' প্রকারের একটি সত্তা সংযুক্তি ব্যর্থ হয়েছে কারণ একই ধরণের অন্য সত্তার ইতিমধ্যে একই প্রাথমিক কী মান রয়েছে। 'সংযুক্তি' পদ্ধতিটি ব্যবহার করার সময় বা গ্রাফের কোনও সত্তার বিরোধী মূল্যের মান থাকলে কোনও সত্তার স্থিতিকে 'অপরিবর্তিত' বা 'পরিবর্তিত' এ সেট করার সময় এটি ঘটতে পারে। এটি হতে পারে কারণ কিছু সত্তা নতুন এবং এখনও ডাটাবেস-উত্পন্ন মূল মানগুলি পায় নি। এই ক্ষেত্রে গ্রাফটি ট্র্যাক করতে 'অ্যাড' পদ্ধতি বা 'যুক্ত' সত্তার স্থিতিটি ব্যবহার করুন এবং তারপরে নন-নতুন সত্তার স্থিতিকে যথাযথ হিসাবে 'অপরিবর্তিত' বা 'পরিবর্তিত' হিসাবে সেট করুন।

কেউ কি আমার কোডটিতে কিছু ভুল দেখেছে বা বুঝতে পারে যে কোন পরিস্থিতিতে কোনও মডেল সম্পাদনার সময় এ জাতীয় ত্রুটি ছুঁড়ে ফেলবে?


আপনি কি সেট স্থাপনের আগে আপনার সত্তাকে সংযুক্ত করার চেষ্টা করেছেন EntityState? যেহেতু আপনার সত্তা কোনও পোস্টের অনুরোধ থেকে আসে, এটি বর্তমান প্রসঙ্গে ট্র্যাক করা উচিত নয়, আমি অনুমান করি যে এটি একটি বিদ্যমান আইডির সাহায্যে আপনি কোনও আইটেম যুক্ত করার চেষ্টা করেছেন বলে বিবেচনা করে
রায়দা মাত্তর

আমি এটি চেষ্টা করেছি এবং ফলাফলটি হুবহু একই :( কিছু কারণে প্রসঙ্গ মনে করে আমি একটি নতুন আইটেম তৈরি করছি, তবে আমি কেবল বিদ্যমানটি আপডেট করছি ...
ক্রিস সিজাক

আমি ত্রুটিটি নিক্ষেপ করার আগে 'ক' এর অবস্থা পরীক্ষা করি এবং এই বস্তুর অবস্থা 'বিচ্ছিন্ন' হয় তবে ডিবিকে ডেকে থাকে s কোন ধারনা?
ক্রিস সিজাক

5
আমি কেবল আপনার আপডেটটি দেখেছি, আপনি কীভাবে আপনার প্রসঙ্গের আজীবন সুযোগটি সেটআপ করলেন? এটা কি অনুরোধ অনুযায়ী? যদি dbউদাহরণস্বরূপ আপনার দুটি কর্মের মধ্যে একই, হিসাবে এটি আপনার আইটেমের GET পদ্ধতি (পরে প্রসঙ্গ দ্বারা ট্র্যাক) দ্বারা লোড হয়, আপনার সমস্যা ব্যাখ্যা করতে পারেন, এবং এটি আপনার পোস্ট পদ্ধতিতে শনাক্ত করতে পারছি পারে সত্তা আগে সংগৃহীত ।
রোদা মাট্টার

1
না canUserAccessA()সরাসরি বা অন্য entitiy একটি সম্পর্ক যেমন সত্তা লোড?
কোডকাস্টার

উত্তর:


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
কিছুটা পরিষ্কার এবং আরও পারফরম্যান্ট: যদি (db.As.AsNoTracking ()। যে কোনও (x => x.aID == এইড && x.UserID == ইউজারআইডি))
ব্রেন্ট

11
দ্রষ্টব্য: আপনার using System.Data.Entity;ব্যবহার করা দরকার AsNoTracking()
ম্যাক্সিম

আমার ক্ষেত্রে সত্তা আইডি ব্যতীত কেবলমাত্র ক্ষেত্রগুলি আপডেট করা ভাল কাজ করেছে: বর্ণ সত্ত্বা = প্রসঙ্গ। খাঁটি.সোমপ্রোপার্টি = নিউভ্যালু; প্রসঙ্গ.এন্ট্রি (সত্তা) .প্রপার্টি (x => x.someProperty) .আইএসএমডিফায়েড = সত্য; context.SaveChanges ();
আন্তন লাহিন

3
ব্যাপক সহায়তা। আমি আমার ফার্স্টঅরডিফল্ট () এর আগে .এএসএনও ট্র্যাকিং () যুক্ত করেছিলাম এবং এটি কাজ করে।
coggicc

109

উত্সাহের ব্যাপার হল:

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

অথবা আপনি এখনও জেনেরিক না হলে:

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

আমার সমস্যাটি সহজেই সমাধান করা যাচ্ছে বলে মনে হচ্ছে


1
আশ্চর্যজনক, এটি আমার দৃশ্যে নিখুঁতভাবে কাজ করেছে যেখানে আমার সংযোগ বিচ্ছিন্ন অ্যাপ্লিকেশনটিতে একটি কাস্টম যোগদানের টেবিল সহ অনেকের কাছে রেকর্ড আপডেট করার প্রয়োজন ছিল। এমনকি ডাটাবেস থেকে সত্তা দখল করার পরেও আমি রেফারেনশিয়াল ত্রুটিগুলি পেয়ে যাচ্ছিলাম; ইত্যাদি I কিন্তু এই অবশেষে কাজ! ধন্যবাদ!!
ফায়ারকেপ

5
এইটা কাজ করে. নোট্র্যাকিং সংযুক্তি এবং ব্যবহার সম্পর্কিত অন্যান্য সমস্ত পরামর্শ ব্যর্থ হওয়ায় আমি ইতিমধ্যে নট্র্যাকিং করছি। সমাধানের জন্য ধন্যবাদ।
খাইনেস্টার

3
কাজের একই ইউনিটের মধ্যে পিতামাতা ও শিশু সত্তা আপডেট করার সময় এটি আমার পক্ষে কাজ করেছিল । অনেক ধন্যবাদ
ইয়ান

55
যে কারও সন্ধানের জন্য, AddOrUpdateনাম System.Data.Entity.Migrationsজায়গার একটি এক্সটেনশন পদ্ধতি ।
নিক

1
@ আরতিমস্কা দুর্ভাগ্যক্রমে আমি জানি না।
guneysus

15

দেখে মনে হচ্ছে আপনি যে সত্তাটি সংশোধন করার চেষ্টা করছেন সেটি সঠিকভাবে ট্র্যাক করা হচ্ছে না এবং তাই এটি সম্পাদিত হিসাবে স্বীকৃত নয়, পরিবর্তে যুক্ত হয়েছে।

সরাসরি স্থিতি স্থাপনের পরিবর্তে নিম্নলিখিতগুলি করার চেষ্টা করুন:

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

এছাড়াও, আমি আপনাকে সতর্ক করতে চাই যে আপনার কোডটিতে সম্ভাব্য সুরক্ষা দুর্বলতা রয়েছে। আপনি যদি নিজের ভিউ মডেলটিতে সরাসরি সত্তা ব্যবহার করছেন, তবে আপনার ঝুঁকি রয়েছে যে কেউ জমা দেওয়া আকারে সঠিকভাবে নাম দেওয়া ক্ষেত্রগুলি যুক্ত করে সত্তার বিষয়বস্তুগুলি সংশোধন করতে পারে। উদাহরণস্বরূপ, যদি ব্যবহারকারী "এ ফার্স্টনাম" নামের সাথে ইনপুট বাক্স যুক্ত করে এবং সত্তার মধ্যে যেমন ক্ষেত্র থাকে তবে মানটি ভিউমডেলের সাথে আবদ্ধ হবে এবং ব্যবহারকারীর অ্যাপ্লিকেশনটির সাধারণ ক্রিয়াকলাপে এটি পরিবর্তন করার অনুমতি দেওয়া হবে না এমনকি ডাটাবেসে সংরক্ষণ করা হবে if ।

হালনাগাদ:

পূর্বে উল্লিখিত সুরক্ষিত দুর্বলতা কাটিয়ে উঠতে আপনার ডোমেন মডেলটি কখনও আপনার ভিউ মডেল হিসাবে প্রকাশ করা উচিত নয় তবে পরিবর্তে পৃথক ভিউ মডেল ব্যবহার করা উচিত। তারপরে আপনার ক্রিয়াকলাপটি ভিউ মডেলটি পাবেন যা আপনি অটোম্যাপারের মতো কিছু ম্যাপিং সরঞ্জাম ব্যবহার করে ডোমেন মডেলটিতে ফিরে ম্যাপ করতে পারেন। এটি আপনাকে সংবেদনশীল ডেটা সংশোধনকারী থেকে সুরক্ষিত রাখবে।

এখানে বর্ধিত ব্যাখ্যা:

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


3
হাই কাস্পারস, ইনপুট দেওয়ার জন্য ধন্যবাদ। সংযুক্তি পদ্ধতিটি আমার প্রশ্নে উল্লিখিত একই ত্রুটি ছুড়ে ফেলে। সমস্যাটি হ'ল canUserAccessA () ফাংশনটি সত্তা লোড করার সাথে সাথে উপরে উল্লিখিত কোডকাস্টারকে বোঝায়। তবে এই বলে যে আমি সুরক্ষার প্রতি আপনার পরামর্শের প্রতি খুব আগ্রহী। আপনি কি পরামর্শ দিতে পারেন যে এই জাতীয় আচরণ রোধ করতে আমার কী করা উচিত?
ক্রিস সিজাক

কীভাবে সুরক্ষা দুর্বলতা রোধ করতে হয় সে সম্পর্কে অতিরিক্ত তথ্যের সাথে আমার উত্তর আপডেট করে।
কাস্পারস ওজলস


11

আমার জন্য স্থানীয় অনুলিপি ছিল সমস্যার উত্স। এটি এটি সমাধান

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

10

আমার কেসটি ছিল আমার আমার এমভিসি অ্যাপ্লিকেশন থেকে 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

আমি এই উত্তরটি কেবল যুক্ত করেছি কারণ সমস্যাটি আরও জটিল ডেটা প্যাটার্নের ভিত্তিতে ব্যাখ্যা করা হয়েছে এবং আমি এখানে বুঝতে অসুবিধা পেয়েছি।

আমি মোটামুটি সহজ অ্যাপ্লিকেশন তৈরি করেছি। এই ত্রুটিটি সম্পাদনা করুন পোস্টের ক্রিয়াকলাপের মধ্যে ঘটেছিল। ক্রিয়াটি ভিউমোডেলটিকে একটি ইনপুট প্যারামিটার হিসাবে গ্রহণ করেছে। ভিউমোডেলটি ব্যবহারের কারণটি ছিল রেকর্ডটি সংরক্ষণের আগে কিছু গণনা করা।

একবার যেমন ক্রিয়াকলাপের মধ্য দিয়ে অ্যাকশনটি পেরিয়ে গেলে if(ModelState.IsValid), আমার ভুলটি হ'ল ভিউমোডেল থেকে সত্তার সম্পূর্ণ নতুন ইভেন্টে মানগুলি প্রজেক্ট করা। আমি ভেবেছিলাম আপডেট হওয়া ডেটা সঞ্চয় করার জন্য আমাকে একটি নতুন উদাহরণ তৈরি করতে হবে এবং তারপরে এ জাতীয় উদাহরণটি সংরক্ষণ করতে হবে।

আমি পরে যা বুঝতে পেরেছিলাম তা হল আমাকে ডাটাবেস থেকে রেকর্ডটি পড়তে হয়েছিল:

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);

একই কী দিয়ে লোড হওয়া বস্তুর সমস্যা হ'ল, তাই প্রথমে আমরা সেই অবজেক্টটিকে আলাদা করব এবং একই কী দিয়ে দুটি বস্তুর মধ্যে দ্বন্দ্ব এড়াতে আপডেট করব do


@ আর্টজম বি একই কী দিয়ে লোড হওয়া সামগ্রীর সমস্যার কারণ, তাই প্রথমে আমরা সেই বস্তুকে আলাদা করব এবং একই কী এর সাথে দুটি বস্তুর মধ্যে দ্বন্দ্ব এড়াতে আপডেট করব
lvl4fi4

2

আমার একই ধরণের সমস্যা ছিল, ২-৩ দিনের জন্য অনুসন্ধানের পরে ".এএসএনও ট্র্যাকিং" সরানো উচিত কারণ EF পরিবর্তনগুলি ট্র্যাক করে না এবং ধরে নেওয়া হয় যে কোনও বস্তু সংযুক্ত না করা থাকলে কোনও পরিবর্তন নেই। এছাড়াও যদি আমরা ব্যবহার না করি .AsNoTracking, EF স্বয়ংক্রিয়ভাবে কোন অবজেক্টটি সংরক্ষণ / আপডেট করতে হবে তা জেনে রাখুন সুতরাং সংযুক্তি / যুক্ত করার প্রয়োজন নেই।


2

AsNoTracking()আপনি যেখানে আপনার ক্যোয়ারী পাচ্ছেন তা ব্যবহার করুন ।

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

2

আমি যেখানে এই ত্রুটি সম্মুখীন

  • দুটি পদ্ধতি, একটি & B এর, একটি একক নিয়ামক উভয় একটি ApplicationDbContext একই উদাহরণস্বরূপ ব্যবহৃত, এবং
  • পদ্ধতি ক নামক পদ্ধতি বি
    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();
    }

আমি ব্যবহারের বিবৃতি পেতে পদ্ধতি বি পরিবর্তন করেছি এবং কেবল স্থানীয় ডিবি 2 এর উপর নির্ভর করি । পরে:

    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

এখানে আমি একই ক্ষেত্রে কি করেছি।

এই সিট্যাচুয়েশন মানে এই যে একই সত্তা ইতিমধ্যে প্রসঙ্গে উপস্থিত রয়েছে following সুতরাং নিম্নলিখিতগুলি সহায়তা করতে পারে

সত্তা প্রসঙ্গে থাকলে প্রথমে চেঞ্জট্র্যাকার থেকে চেক করুন

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

আমি রাষ্ট্র আপডেট করে সমস্যাটি সমাধান করতে চাই man আপনি যখন ট্রিগার সন্ধান করেন বা একই রেকর্ড সেটে অন্য কোনও ক্যোয়ারী ক্রিয়াকলাপ সংশোধন করে আপডেট করা হয়েছে তখন আমাদের স্থিতি বিচ্ছিন্ন করতে হবে তখন আপনি নিজের আপডেট পরিবর্তনটি সরিয়ে দিতে পারেন

     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.mic Microsoft.com/ Forums/ sqlserver/ es- ES/ b4b350ba- b0d5-464d- 8656-8c117d55b2af/ problema- al- modificar- en- entity- framework? forum = vcses স্প্যানিশ হয় (দ্বিতীয় উত্তরের সন্ধান করুন)


শুধু সতর্কতা অবলম্বন করা আবশ্যক এবং শুধুমাত্র ডাটাবেসের conexion 1 উদাহরণস্বরূপ ব্যবহার করেন, বিশেষভাবে আপনি সত্তা ফ্রেমওয়ার্ক ব্যবহার করছেন কিনা তা যদি আপনি এটি না আপনি যদি ভুল সত্তা ফ্রেমওয়ার্ক একটি সত্তা বস্তুর IEntityChangeTracker একাধিক দৃষ্টান্ত দ্বারা সমর্থিত না করতে পারেন হবে
Suzume

1

আপনি যেমন যুক্ত পদ্ধতি ব্যবহার করতে পারেন;

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

তবে অনেক ক্ষেত্রে আপনি যদি সেই সময়ে একাধিক মডেল ব্যবহার করতে চান তবে এটি কাজ করবে না কারণ সত্তা ইতিমধ্যে অন্য সত্তার সাথে সংযুক্ত। সুতরাং, সেই সময়ে আপনি ADDOrUpdate সত্তা মাইগ্রেশন পদ্ধতিটি ব্যবহার করতে পারেন যা কেবলমাত্র এক থেকে অন্যটিতে স্থানান্তরিত করে এবং ফলস্বরূপ আপনি কোনও ত্রুটি পাবেন না।

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

0

সমস্ত রাজ্য সাফ করুন

dbContextGlobalERP.ChangeTracker.Entries ()। যেখানে (e => e.Entity! = নাল) .ToList ()। forEach (e => e.State = EntityState.Detached);

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.