آموزشگاه برنامه نویسی تحلیل داده
آموزشگاه برنامه نویسی تحلیل داده

آموزش Edit داده در سناریوی disconnected در Entity Framework Core

دوره های مرتبط با این مقاله

آموزش Edit داده در سناریوی disconnected در Entity Framework Core

آموزش Edit داده در سناریوی disconnected در Entity Framework Core

EF Core API دستور UPDATE را برای موجودیت هایی که EntityState شان Modified باشد در Database می سازذ و اجرا می کند. در سناریوی connected، کلاس DbContext موجودیت هایی را که تغییر کرده اند track می کند و در نتیجه خودکار State آن ها را به Modified تغییر می دهد.

ذخیره ی Data در سناریوی disconnected کمی متفاوت است. در سناریوی disconnected ، شی DbContext اطلاعی از موجودیت ها ندارد چرا که موجودیت ها خارج از scope نمونه ی فعلی DbContext تغییر کرده اند. پس باید موجودیت های disconnected را با EntityState Modified به context اصطلاحا attatch کنیم.

جدول زیر متدهای DbContext و DbSet که برای update موجودیت ها به کار می رود نشان می دهد:

DbContext متدهای
DbSet متدهای
توضیح
DbContext.Update
DbSet.Update
یک موجودیت را با ModifiedState به dbContext اصطلاحا attach می کند.
DbContext.UpdateRange
DbSet.UpdateRange
دسته ای موجودیت را با ModifiedState به dbContext اصطلاحا attach می کند.

مثال زیر update یک موجودیت disconnected را نشان می دهد:


// Disconnected Student entity
var stud = new Student(){ StudentId = 1, Name = "Bill" };
stud.Name = "Steve"; 
using (var context = new SchoolContext())
{
 context.Update< Student >(stud);
 // or the followings are also valid
 // context.Students.Update(stud);
 // context.Attach< Student >(stud).State = EntityState.Modified;
 // context.Entry< Student >(stud).State = EntityState.Modified; 
 context.SaveChanges(); 
}

در مثال بالا، فرض کنید stud یک موجودیت از نوع Student است که قبلا در Database موجود بوده و مقداری صحیح برای key property آن ست شده (StudentId = 1).

Entity Framework Core متد DbContext.Update() را معرفی کرده است که یک موجودیت تعیین شده را به context اصطلاحا attach می کند و EntityState آن را به Modified تغییر می دهد. به جای این متد، می توانید از متدDbSet.Update() (به صورت context.Students.Update(stud)) نیز استفاده کنید.

مثال بالا دستور UPDATE زیر را در Database اجرا می کند:


exec sp_executesql N'SET NOCOUNT ON;
UPDATE [Students] SET [Name] = @p0
WHERE [StudentId] = @p1;
SELECT @@ROWCOUNT;
',N'@p1 int,@p0 nvarchar(4000)',@p1=1,@p0=N'Steve'
go

آموزش update کردن چند موجودیت در Entity Framewok Core

از متدهای DbContext.UpdateRange یا DbSet.UpdateRange برای attach کردن یک مجموعه یا آرایه از موجودیت ها به DbContext و تغییر EntityState آن ها به Modified در یک ارتباط با Database، استفاده کنید.


var modifiedStudent1 = new Student()
{
 StudentId = 1,
 Name = "Bill"
};
var modifiedStudent2 = new Student()
{
 StudentId = 3,
 Name = "Steve"
};
var modifiedStudent3 = new Student()
{
 StudentId = 3,
 Name = "James"
};
IList< Student > modifiedStudents = new List< Student >()
{
 modifiedStudent1,
 modifiedStudent2,
 modifiedStudent3
};
using (var context = new SchoolContext())
{
 context.UpdateRange(modifiedStudents);
 
 // or the followings are also valid
 //context.UpdateRange(modifiedStudent1, modifiedStudent2, modifiedStudent3);
 //context.Students.UpdateRange(modifiedStudents);
 //context.Students.UpdateRange(modifiedStudent1, modifiedStudent2, modifiedStudent3);
    
 context.SaveChanges();
}

همان طور که می بینید متد UpdateRange دو overload داد. یکی از آن ها یک collection از موجودیت ها را به عنوان ورودی می گیرد و دیگری آرایه object[] را به عنوان ورودی می گیرد. متد DbSet.UpdateRange کارکردی مشابه متد DbContext.UpdateRange دارد.

Core عملکرد کار با Database را با اجرای دستور Update برای همه ی موجودیت های بالا در یک database round trip، بهبود بخشیده است. مثال بالا بصورت زیر در Database اجرا می شود:


exec sp_executesql N'SET NOCOUNT ON;
UPDATE [Students] SET [Name] = @p0
WHERE [StudentId] = @p1;
SELECT @@ROWCOUNT;
UPDATE [Students] SET [Name] = @p2
WHERE [StudentId] = @p3;
SELECT @@ROWCOUNT;
UPDATE [Students] SET [Name] = @p4
WHERE [StudentId] = @p5;
SELECT @@ROWCOUNT;
',N'@p1 int,@p0 nvarchar(4000),@p3 int,@p2 nvarchar(4000),@p5 int,@p4 nvarchar(4000)',
@p1=1,@p0=N'Bill',@p3=2,@p2=N'Steve',@p5=3,@p4=N'James'
go

آموزش تغییر EntityState در Entity Framewok Core

در Entity Framework Core 2.x، متد Update مقدار EntityState را براساس مقدار key property موجودیت ست می کند. اگر key property موجودیت child یا root خالی، null یا مقدار پیش فرض باشد، متد Update() آن را یک موجودیت جدید در نظر می گیرد و EntityState آن را به Added تغییر می دهد.


public static void Main()
{
 var newStudent = new Student()
 {
  Name = "Bill"
 };
 var modifiedStudent = new Student()
 {
  StudentId = 1,
  Name = "Steve"
 };
 using (var context = new SchoolContext())
 {
  context.Update< Student >(newStudent);
  context.Update< Student >(modifiedStudent);
  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: Student, State: Modified

در مثال بالا newStudent مقداری برای key property خود (StudentId) ندارد. متد Update() آن را به صورت Added نشانه گذاری می کند. حال آنکه modifiedStudent مقدار برای key property خود دارد، پس به صورت Modified نشانه گذاری می شود.
Exception:

درصورتی که شی DbContext از قبل موجودیتی با مقدار key property مشابه track می کرده، متدهای Update و UpdateRange باعث رخداد InvalidOperationException می شوند. مثال زیر را در نظر بگیرید:


var student = new Student()
{
 StudentId = 1,
 Name = "Steve"
};
using (var context = new SchoolContext())
{
 // loads entity in a conext whose StudentId is 1
 context.Students.First< Student >(s => s.StudentId == 1); 
 // throws an exception as it already tracking entity with StudentId=1
 context.Update< Student >(student); 
 context.SaveChanges();
}

در مثال بالا، شی context یک بار موجودیت Student با StudentId برابر 1 را load کرده .پس attach کردن یک موجودیت با همان مقدار key property مشابه، موجب خطای زیر می شود:


The instance of entity type 'Student' cannot be tracked because another instance with the same key value for {'StudentId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.

در بخش بعد به آموزش نحوه حذف رکورد در سناریوی disconnected می پردازیم.

  • 133
  •    44
  • تاریخ ارسال :   1398/07/25

دانلود فیلم آموزشی دانشجویان گرامی اگر این مطلب برای شما مفید بود لطفا ما را در GooglePlus محبوب کنید
رمز عبور: tahlildadeh.com یا www.tahlildadeh.com
ارسال دیدگاه نظرات کاربران
شماره موبایل دیدگاه
عنوان پست الکترونیک

ارسال

آموزشگاه برنامه نویسی تحلیل داده
آموزشگاه برنامه نویسی تحلیل داده

تمامی حقوق این سایت متعلق به آموزشگاه تحلیل داده می باشد .