প্রদত্ত কোডে ত্রুটির কারণ নিম্নলিখিত।
আপনি যখন Aডাটাবেস থেকে সত্তা তৈরি করেন তার সম্পত্তি Sদুটি নতুন রেকর্ড রয়েছে এমন একটি সংগ্রহের মাধ্যমে শুরু করা হয় B। Idএই নতুন Bসত্ত্বার প্রত্যেকটির সমান 0।
// This line of code reads entity from the database
// and creates new instance of object A from it.
var a = db.Set<A>().Single();
// When new entity A is created its field S initialized
// by a collection that contains two new instances of entity B.
// Property Id of each of these two B entities is equal to 0.
public ICollection<B> S { get; set; } = new List<B>() { new B {}, new B {} };
সত্তার কোড var a = db.Set<A>().Single()সংগ্রহের লাইন কার্যকর করার পরে ডাটাবেস থেকে সত্ত্বা থাকে না , কারণ অলস লোডিং ব্যবহার করে না এবং সংগ্রহের কোনও সুস্পষ্ট লোডিং নেই । সত্তা শুধুমাত্র নতুন ধারণ সত্ত্বা সংগ্রহ আরম্ভের সময় তৈরি হওয়া ।SABDbContext DbSABS
আপনি যখন IsModifed = trueসংগ্রহ Sসত্তার কাঠামোর জন্য কল করেন তখন সেই দুটি নতুন প্রবেশকে Bপরিবর্তন ট্র্যাকিংয়ের সাথে যুক্ত করার চেষ্টা করে । তবে এটি ব্যর্থ হয়েছে কারণ দুটি নতুন Bসত্তারই একই রকম Id = 0:
// This line tries to add to change tracking two new B entities with the same Id = 0.
// As a result it fails.
db.Entry(a).Collection(x => x.S).IsModified = true;
স্ট্যাক ট্রেস থেকে আপনি দেখতে পাচ্ছেন যে সত্তা কাঠামোটি Bসত্তাগুলিকে এতে সন্নিবেশ করার চেষ্টা করেছে IdentityMap:
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.ThrowIdentityConflict(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry, Boolean updateDuplicate)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetPropertyModified(IProperty property, Boolean changeState, Boolean isModified, Boolean isConceptualNull, Boolean acceptChanges)
at Microsoft.EntityFrameworkCore.ChangeTracking.NavigationEntry.SetFkPropertiesModified(InternalEntityEntry internalEntityEntry, Boolean modified)
at Microsoft.EntityFrameworkCore.ChangeTracking.NavigationEntry.SetFkPropertiesModified(Object relatedEntity, Boolean modified)
at Microsoft.EntityFrameworkCore.ChangeTracking.NavigationEntry.set_IsModified(Boolean value)
এবং ত্রুটি বার্তাটি আরও বলেছে যে এটি Bসত্তার সাথে ট্র্যাক করতে পারে না Id = 0কারণ এর সাথে অন্য একটি Bসত্তা Idইতিমধ্যে ট্র্যাক করা হয়েছে।
কিভাবে এই সমস্যার সমাধান.
এই সমস্যার সমাধানের জন্য আপনার সংগ্রহটি Bআরম্ভ করার সময় সত্তা তৈরি করে এমন কোড মুছে ফেলা উচিত S:
public ICollection<B> S { get; set; } = new List<B>();
পরিবর্তে আপনার Sযেখানে Aতৈরি করা হয়েছে সেখানে সংগ্রহ পূরণ করা উচিত । উদাহরণ স্বরূপ:
db.Add(new A {S = {new B(), new B()}});
আপনি যদি অলস লোডিং ব্যবহার না Sকরেন তবে এর আইটেমগুলি পরিবর্তন ট্র্যাকিংয়ে যুক্ত করার জন্য আপনার সংগ্রহটি স্পষ্টভাবে লোড করা উচিত :
// Use eager loading, for example.
A a = db.Set<A>().Include(x => x.S).Single();
db.Entry(a).Collection(x => x.S).IsModified = true;
এটি খ এর দৃষ্টান্ত সংযুক্ত করার পরিবর্তে কেন যুক্ত হয় না?
সংক্ষেপে , তারা যুক্ত হওয়ার ইচ্ছার সাথে যুক্ত থাকে কারণ তাদের Detachedরাষ্ট্র রয়েছে।
কোড লাইন কার্যকর করার পরে
var a = db.Set<A>().Single();
সত্তার তৈরি দৃষ্টান্তগুলির Bরাষ্ট্র রয়েছে Detached। এটি পরবর্তী কোড ব্যবহার করে যাচাই করা যেতে পারে:
Console.WriteLine(db.Entry(a.S[0]).State);
Console.WriteLine(db.Entry(a.S[1]).State);
তারপর আপনি যখন সেট
db.Entry(a).Collection(x => x.S).IsModified = true;
EF Bট্র্যাকিং পরিবর্তন করতে সত্তা যুক্ত করার চেষ্টা করে । ইসিফোরের উত্স কোড থেকে আপনি দেখতে পাচ্ছেন যে এটি আমাদের অভ্যন্তরীণতা- এন্ট্রি পদ্ধতির দিকে নিয়ে যায় etসেটপ্রোপার্টিটি পরবর্তী যুক্তির মানগুলির সাথে সংশোধিত :
property- আমাদের Bসত্তার একটি,
changeState = true,
isModified = true,
isConceptualNull = false,
acceptChanges = true।
এই জাতীয় যুক্তিযুক্ত এই পদ্ধতিটি Detached Bএন্টিগুলির স্থিতিতে পরিবর্তন করে Modifiedএবং তারপরে তাদের ট্র্যাকিং শুরু করার চেষ্টা করে (লাইন 490 - 506 দেখুন)। কারণ Bসত্তাগুলির এখন অবস্থা রয়েছে Modifiedএটি এগুলি সংযুক্ত হওয়ার দিকে পরিচালিত করে (যোগ করা হয়নি)।