مشخصات مقاله
-
0
-
0.0
-
2678
-
0
-
0
آموزش کار با Disconnected Entity Graph در Entity Framework Core
آموزش کار با Disconnected Entity Graph در Entity Framework Core
در بخش های قبل یاد گرفتیم که چگونه ChangeTracker به صورت خودکار EntityState هر موجودیت در سناریوی connected را تغییر می دهد. در این بخش درمورد تاثیر متدهای مختلف روی موجودیت اصلی و موجودیت های وابسته یک disconnected entity graph در Entity Framework Core صحبت می کنیم.
Entity Framework Core متدهایی در اختیار می گذارد که نه تنها یک موجودیت را به context اصطلاحا attach می کند، بلکه EntityState هر موجودیت درون یک disconnected entity graph تغییر می دهد.
Attach()Entry()Add()Update()Remove()
می خواهیم ببینیم متدهای بالا چگونه EntityState هر موجودیت در یک گراف موجودیت را در Entity Framework Core 2.x تغییر می دهد.
متد Attach()
متدهای DbContext.Attach() DbSet.Attach() گراف موجودیت disconnected تعیین شده را attach می کند و شروع به track آن می کند.
مثال زیر رفتار متد DbContext.Attach() و تاثیر آن روی EntityState هر موجودیت در یک گراف را نشان می دهد:
public static void Main()
{
var stud = new Student() { //Root entity (empty key)
Name = "Bill",
Address = new StudentAddress() //Child entity (with key value)
{
StudentAddressId = 1,
City = "Seattle",
Country = "USA"
},
StudentCourses = new List< StudentCourse >() {
new StudentCourse(){ Course = new Course(){ CourseName = "Machine Language" } },//Child entity (empty key)
new StudentCourse(){ Course = new Course(){ CourseId = 2 } } //Child entity (with key value)
}
};
var context = new SchoolContext();
context.Attach(stud).State = EntityState.Added;
DisplayStates(context.ChangeTracker.Entries());
}
private static void DisplayStates(IEnumerable< EntityEntry > entries)
{
foreach (var entry in entries)
{
Console.WriteLine($"Entity: {entry.Entity.GetType().Name},
State: {entry.State.ToString()} ");
}
}Output: Entity: Student, State: Added Entity: StudentAddress, State: Unchanged Entity: StudentCourse, State: Added Entity: Course, State: Added Entity: StudentCourse, State: Added Entity: Course, State: Unchanged
در مثال بالا، stud یک Instance از گراف موجودیت Student است که حاوی reference هایی به دو موجودیت StudentAddress و StudentCourse است. کد context.Attach(stud).State = EntityState.Added گراف موجودیت stud را به Context اصطلاحا attach می کند و state آن را به Added تغییر می دهد.
متد Attach() ، مقدار EntityState موجودیت root (در اینجا Student) را به Added تغییر می دهد، چه مقدار key داشته باشد چه نداشته باشد. اگر یک موجودیت وابسته حاوی مقداری برای key خود باشد، به صورت Unchanged، و در غیر این صورت با Added نشانه گذاری می شود. خروجی مثال بالا نشان می دهد EntityState برای موجودیت Student به Added ست شده و موجودیت های وابسته آن با مقدار key مناسب Unchanged EntityState دارند و آن هایی که مقدار key ندارند Added state دارند.
جدول زیر رفتار متد Attach() را هنگام تعیین EntityState برای گراف موجودیت هایی که disconnected هستند نشان می دهد:
متد Entry()
متد DbContext.Entry() در EF Core متفاوت از EF 6.x عمل می کند. مثال زیر را در نظر بگیرید:
var student = new Student() { //Root entity (empty key)
Name = "Bill",
Address = new StudentAddress() //Child entity (with key value)
{
StudentAddressId = 1,
City = "Seattle",
Country = "USA"
},
StudentCourses = new List< StudentCourse >() {
new StudentCourse(){ Course = new Course(){ CourseName="Machine Language" } },//Child entity (empty key)
new StudentCourse(){ Course = new Course(){ CourseId=2 } } //Child entity (with key value)
}
};
var context = new SchoolContext();
context.Entry(student).State = EntityState.Modified;
DisplayStates(context.ChangeTracker.Entries());
Output: Entity: Student, State: Modified
در مثال بالا، کد context.Entry(student).State = EntityState.Modified موجودیت را به context اصطلاحا attach می کند و EntityState تعیین شده را به root entity می دهد، و داشتن یا نداشتن مقدار برای key property آن اهمیت ندارد. تمام موجودیت های وابسته در گراف را نادیده می گیرد و آن ها را attach نمی کند، و EntityState آن ها را نیز تغییر نمی دهد.
جدول زیر رفتارهای مختلف متد DbContext.Entry() را نشان می دهد:
متد Add()
متدهای DbContext.Add و DbSet.Add یک گراف موجودیت را به context اصطلاحا attach می کنند و EntityState موجودیت root و موجودیت های وابسته آن را به Added تغییر می دهند. داشتن یا نداشتن مقدار برای key property آن ها اهمیت ندارد.
var student = new Student() { //Root entity (with key value)
StudentId = 1,
Name = "Bill",
Address = new StudentAddress() //Child entity (with key value)
{
StudentAddressId = 1,
City = "Seattle",
Country = "USA"
},
StudentCourses = new List< StudentCourse >() {
new StudentCourse(){ Course = new Course(){ CourseName="Machine Language" } },//Child entity (empty key)
new StudentCourse(){ Course = new Course(){ CourseId=2 } } //Child entity (with key value)
}
};
var context = new SchoolContext();
context.Students.Add(student);
DisplayStates(context.ChangeTracker.Entries())Output: Entity: Student, State: Added Entity: StudentAddress, State: Added Entity: StudentCourse, State: Added Entity: Course, State: Added Entity: StudentCourse, State: Added Entity: Course, State: Added
جدول زیر EntityState های ممکن در گراف را هنگام استفاده از متدهای DbContext.Add و DbSet.Add نشان می دهد:
Update()
متدهای DbContext.Update() DbSet.Update() یک گراف موجودیت را به context اصطلاحا attach می کنند و EntityState همه ی موجودیت ها در یک گراف را براساس مقدار داشتن key property شان تعیین می کنند. مثال زیر را در نظر بگیرید:
var student = new Student() { //Root entity (with key value)
StudentId = 1,
Name = "Bill",
Address = new StudentAddress() //Child entity (with key value)
{
StudentAddressId = 1,
City = "Seattle",
Country = "USA"
},
StudentCourses = new List< StudentCourse >() {
new StudentCourse(){ Course = new Course(){ CourseName="Machine Language" } },//Child entity (empty key)
new StudentCourse(){ Course = new Course(){ CourseId=2 } } //Child entity (with key value)
}
};
var context = new SchoolContext();
context.Update(student);
DisplayStates(context.ChangeTracker.Entries());
Output: Entity: Student, State: Modified Entity: StudentAddress, State: Modified Entity: StudentCourse, State: Added Entity: Course, State: Added Entity: StudentCourse, State: Added Entity: Course, State: Modified
در مثال بالا، متد Update() به entity هایی که key property هایشان مقدار دارند، Modified state می دهد و به entity هایی که key property هایشان مقدار ندارند یا مقادیر پیش فرض دارند، Modified state می دهد. Root یا child بودن موجودیت اهمیت ندارد.
متد Remove()
متدهای DbContext.Remove() و DbSet.Remove () مقدار EntityState موجودیت root را به Deleted تغییر می دهد.
var student = new Student() { //Root entity (with key value)
StudentId = 1,
Name = "Bill",
Address = new StudentAddress() //Child entity (with key value)
{
StudentAddressId = 1,
City = "Seattle",
Country = "USA"
},
StudentCourses = new List< StudentCourse >() {
new StudentCourse(){ Course = new Course(){ CourseName="Machine Language" } },//Child entity (empty key)
new StudentCourse(){ Course = new Course(){ CourseId=2 } } //Child entity (with key value)
}
};
var context = new SchoolContext();
context.Remove(student);
DisplayStates(context.ChangeTracker.Entries());
Output: Entity: Student, State: Deleted Entity: StudentAddress, State: Unchanged Entity: StudentCourse, State: Added Entity: Course, State: Added Entity: StudentCourse, State: Added Entity: Course, State: Unchanged
جدول زیر رفتار متد Remove() و تاثیر آن روی EntityState هر موجودیت را نشان می دهد:
در بخش بعد به بحث درمورد متد ChangeTracker.TrackGraph() برای دستکاری هر موجودیت در گراف موجودیت می پردازیم.