প্রদত্ত কোডে ত্রুটির কারণ নিম্নলিখিত।
আপনি যখন 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()
সংগ্রহের লাইন কার্যকর করার পরে ডাটাবেস থেকে সত্ত্বা থাকে না , কারণ অলস লোডিং ব্যবহার করে না এবং সংগ্রহের কোনও সুস্পষ্ট লোডিং নেই । সত্তা শুধুমাত্র নতুন ধারণ সত্ত্বা সংগ্রহ আরম্ভের সময় তৈরি হওয়া ।S
A
B
DbContext Db
S
A
B
S
আপনি যখন 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
এটি এগুলি সংযুক্ত হওয়ার দিকে পরিচালিত করে (যোগ করা হয়নি)।