اپدیت کردن داده در دیتابیس با استفاده از EF Core در روش Disconnected Scenario

اپدیت کردن داده در دیتابیس با استفاده از EF Core در روش Disconnected Scenario

در این پست از وبسایت پرووید در رابطه با اپدیت کردن داده در دیتابیس با استفاده از EF Core در روش Disconnected Scenario #1 صحبت خواهیم کرد. تکنولوژی Entity Framework Core نسل بعدی Entity Framework است که توسط مایکروسافت معرفی شده است.

در این آموزش از وبسایت پرووید در رابطه با update کردن داده ها در Entity Framework Core و در disconnected scenario صحبت خواهیم کرد. در یکی دیگر از آموزش های قبلی در رابطه با درج کردن داده ها در EF Core در disconnected scenario صحبت کرده بودیم. خب، بحثمان را آغاز می کنیم.

اپدیت کردن داده در دیتابیس با استفاده از EF Core در روش Disconnected Scenario

همانطور که ممکن است تا به حال دانسته باشید EF Core API برای تمامی entity هایی که EntityState آنها با مقدار Modified تنظیم شده است دستورات SQL برای update کردن آنها صادر می کند. این موضوع به طور خودکار برای تمامی entity هایی که توسط کلاس context ردیابی یا اصطلاحاً track می شوند صدق می کند.

بسته ی آموزش ویدئویی نکات طلایی Entity Framework برای برنامه های تجاری سری دوم

از شما دعوت می کنیم که از بسته ی آموزش ویدئویی نکات طلایی Entity Framework  برای برنامه های تجاری سری دوم دیدن کنید.

به عبارت دیگر، کلاس context به طور خودکار می داند کدام entity ها تغییر کرده اند و EntityState آنها را بر روی Modified تنظیم می کند و به این ترتیب در زمان صدا زدن متد SaveChanges دستور UPDATE مناسب برای اجرا شدن بر روی دیتابیس ایجاد می شود. توصیه می کنیم بسته ی آموزش ویدئویی Entity Framework 5 از وبسایت پرووید را حتماً استفاده کنید.

اما در disconnected scenario شرایط کمی متفاوت است. در disconnected scenario، مثلاً در web application ها، Entity Framework Core و کلاس context نمی دانند کدام یک از entity ها تغییر کرده اند چرا که طبیعتاً آن entity ها track نمی شوند. دلیل این موضوع هم این است که دو شی مختلف از کلاس context برای بازیابی و ذخیره کردن داده ها بر روی دیتابیس استفاده می شود.

بنابراین، ابتدا باید آن entity ها attach شوند. این موضوع با تنظیم کردن مقدار Modified برای EntityState آنها انجام می شود. این کار باعث می شود که شی context فعلی که طبیعاتاً از شی context ای که با استفاده از آن داده ها از دیتابیس خوانده شدند متفاوت است، از حضور entity هایی که تغییر کرده اند و باید با دستور UPDATE در دیتابیس به روز رسانی شوند مطلع گردد. به منظور درک کردن بهتر چالش های disconnected scenario توصیه می کنیم بسته ی آموزش ویدئویی نکات طلایی Entity Framework برای برنامه های تجاری را استفاده کنید.

در جدول زیر لیست متدهای DbSet و DbContext که به منظور update کردن entity ها استفاده می شوند را مشاهده می کنید.

update ef core - اپدیت کردن داده در دیتابیس با استفاده از EF Core در روش Disconnected Scenario

علاوه بر این، کد زیر نحوه ی انجام عملیات update کردن entity ها در disconnected scenario را نشان می دهد.

// 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 وجود دارد. از آنجایی که این شی یک مقدار در primary key خود یعنی StudentId = 1 دارد، باید به این نتیجه رسید که این شی از قبل در دیتابیس وجود داشته است و در واقع شی جدیدی نیست که نیاز به درج شدن داشته باشد.

بسته ی آموزش ویدئویی شروع به کار با Entity Framework Core 2.0

از شما دعوت می کنیم که از بسته ی آموزش ویدئویی شروع به کار با Entity Framework Core 2.0 دیدن کنید.

پس از آن با استفاده از متد Update از کلاس DbContext عملیات attach کردن این entity و تنظیم کردن Modified برای EntityState انجام شده است. علاوه بر این متد، می توانید از متد Update از کلاس DbSet نیز استفاده کنید. در واقع برای انجام این کار باید context.Students.Update(stud) را وارد کنید. اجرا شدن دستورات بالا باعث ایجاد شدن دستور UPDATE زیر در دیتابیس و به روزرسانی شدن stud می شود. این موضوع نیز در کد زیر نشان داده شده است.

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

به منظور مطالعه دقیق تر موضوعات مختلف مربوط به Entity Framework توصیه می کنیم حتماً از بسته ی آموزش ویدئویی Entity Framework 6 از وبسایت پرووید استفاده کنید.

update کردن چندین entity در EF Core در disconnected scenario

به منظور انجام به روزرسانی برای بیش از یک شی از متدهای DbContext.UpdateRange و DbSet.UpdateRange استفاده می کنیم. با استفاده از این متدها می توانیم یک آرایه یا collection از entity ها را به منظور تنظیم شدن EntityState آنها با مقدار Modified به این متدها پاس بدهیم. در بسته ی آموزش ویدئویی Collection ها و بسته ی آموزش ویدئویی Collection های همروند می توانید مباحث مربوط به collection ها را دقیق تر بررسی کنید.

خب، لطفاً کدی که در قسمت زیر نوشته شده است را با دقت نگاه کنید.

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 می باشد. اولین overload یک collection از entity ها را دریافت می کند و دومین overload یک آرایه از نوع object را دریافت می کند. ضمناً هر دو متد DbSet.UpdateRange و DbContext.UpdateRange کار یکسانی را انجام می دهند. به منظور بررسی دقیق تر مباحث مربوط به overload کردن متدها و مباحث شی گرایی در سی شارپ از بسته ی آموزش ویدئویی شی گرایی در سی شارپ وبسایت پرووید استفاده کنید.

نکته ی بسیار مهمی که در زمان update کردن یک collection از entity ها باید به آن اشاره کنیم این است که در performance در EF core به مراتب بهبود یافته است. در واقع در چنین شرایطی تمامی دستورات update در یک round trip تک به دیتابیس انجام می شوند. این موضوع در زمانی که قصد درج کردن یک collection از entity ها را دارید و دستورات INSERT متعددی باید در دیتابیس اجرا شوند نیز صدق می کند. این موضوع در آموزش رایگان درج کردن داده ها در disconnected scenario بررسی شد. لطفاً دستورات SQL زیر که در اثر دستورات سی شارپ بالا اجرا می شوند را ببیند. اجرا شدن تمامی این دستورات در یک round trip تک به دیتابیس انجام می گردند.

تغییر مقدار EntityState

متد Update که در بالا بررسی شدند مقدار EntityState را بر اساس مقدار پروپرتی key تنظیم می کند. به عبارتی اگر پروپرتی key از root entity یا child entity خالی یا null و یا default value یک type باشد، سپس متد Update مقدار EntityState را بر روی Added تنظیم می کند. ضمناً منظور از default value یک type همان مقدار پیش فرض است. مثلاً مقدار پیش فرض یک int به عنوان یک type عدد صفر است. یعنی اگر یک متغیر از نوع int تعریف کرده باشید و در آن مقداری قرار نداده باشید مقدار پیش فرض آن صفر است. به منظور درک بهتر این مباحث توصیه می کنیم حتماً بسته ی آموزش ویدئویی سی شارپ از وبسایت پرووید را استفاده کنید.

کد زیر که به صورت عملی این مبحث را به تصویر کشیده است را بررسی کنید.

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()} ");
    }
}

Change in EntityState - اپدیت کردن داده در دیتابیس با استفاده از EF Core در روش Disconnected Scenario

در مثال بالا، newStudent مقداری برای StudentId خود تعریف نکرده است. به عبارت دیگر، مقدار پروپرتی newStudent یا null است یا خالی و یا مقدار پیش فرض. این موضوع باعث می شود که متد Update مقدار EntityState را Added در نظر بگیرد. اما modifiedStudent در پروپرتی key خود یک مقدار دارد، پس متد Update مقدار Modified را برای EntityState آن در نظر می گیرد. توصیه می کنیم که به منظور درک بهتر این مباحث از بسته ی آموزش ویدئویی Entity Framework Core سری اول و Entity Framework Core سری دوم استفاده کنید.

بسته ی آموزش ویدئویی شروع به کار با Entity Framework Core 2.0

از شما دعوت می کنیم که از بسته ی آموزش ویدئویی شروع به کار با Entity Framework Core 2.0 دیدن کنید.

برای مبحثی که مطرح کردیم یک استثنا نیز وجود دارد. متدهای Update و UpdateRange برای entity هایی که توسط کلاس context در حال track شدن هستند و دقیقاً با همان key در متدهای Update و UpdateRange مورد استفاده قرار می گیرند یک InvalidOperationException را throw می کنند. این موضوع در کد زیر به تصویر کشیده شده است.

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

توصیه می کنیم حتماً بسته ی آموزش Entity Framework در برنامه های تجاری سری اول و بسته ی آموزش Entity Framework در برنامه های تجاری سری دوم را در رابطه با این مباحث استفاده کنید.

در کدی که در قسمت بالا مشاهده می کنید کلاس context یک entity از نوع student را load می کند. مقدار StudentId از این student یک است. این load کردن باعث می شود که این entity توسط context رد گیری یا track شود. بنابراین attach کردن یک entity دیگر با یک مقدار یکسان (یعنی همان یک) در پروپرتی key باعث throw شدن exception می شود. در رابطه با رفع exception ها و انجام debugging در سی شارپ و ویژوال استادیو توصیه می کنیم بسته ی آموزش ویدئویی debugging از وبسایت پرووید را استفاده کنید. متن زیر نشان دهنده ی exception ای است که throw می شود.

امیدواریم که این آموزش از وبسایت پرووید نیز مورد توجه شما دوستان عزیز قرار گرفته باشد. ضمناً، برای مشاهده ی سرفصل تمامی دروس موجود در این دوره ی آموزشی به آموزش Entity Framework Core و دسترسی به داده ها رجوع کنید.

مرتضی گیتی
بدون نظر

ارسال نظر

نظر
نام
ایمیل
وب سایت