شروع دوره پایتون از پنجشنبه 1 خرداد ، مقدماتی تا پیشرفته، بدون پیش نیاز شروع دوره پایتون از پنجشنبه 1 خرداد ، مقدماتی تا پیشرفته، بدون پیش نیاز
🎯 ثبت نام
بستن تبلیغات
تسلط کامل بر سی‌شارپ با یک دوره پروژه‌محور

یادگیری سی شارپ از مفاهیم پایه تا پروژه محور: شی‌گرایی، کار با SQL و LINQ، ORMها (Entity Framework)، ساخت پروژه مدیریت رستوران با گزارشات حرفه‌ای و امکانات کامل!

مشاهده بیشتر
تسلط جامع بر MVC Core برای توسعه وب حرفه‌ای

یادگیری MVC Core از مبانی تا پیشرفته: شی‌گرایی، Routing، Entity Framework، امنیت، تست یونیت، Razor، Ajax، و پروژه‌های کاربردی! یک دوره کامل برای تسلط بر توسعه وب با ASP.NET Core. به صورت حضوری و آنلاین!

مشاهده بیشتر

استفاده از مدل برنامه نویسی ناهمزمان و رویه های ذخیره شده با EF در MVC

استفاده از مدل برنامه نویسی ناهمزمان و رویه های ذخیره شده با EF در یک برنامه ی تحت وب ASP.NET MVC

در مباحث قبلی با نحوه ی خواندن و بروز رسانی داده ها با استفاده از مدل برنامه نویسی هزمان (synch programming model) آشنا شدید. در این آموزش نحوه ی پیاده سازی مدل برنامه نویسی ناهمزمان را فراخواهید گرفت. Asynchronous code با استفاده ی بهینه از منابع سرور، کارایی برنامه را بالا می برد. در مقاله ی حاضر، چگونگی استفاده از stored procedure ها برای اجرای عملیات insert، update و delete بر روی یک موجودیت را خواهید آموخت.
در زیر تصاویر برخی از صفحاتی را که با آن ها کار خواهید کرد، مشاهده می کنید:


آموزش MVC
آموزش MVC

چرا استفاده از asynchronous code توصیه می شود


تعداد thread هایی که در دسترس یک سرور وب قرار دارد محدود است و در مواقعی که بارگذاری سنگین در حال اجرا است، تمامی thread ها بکار گرفته می شوند. در صورت به وجود آمدن چنین شرایطی، سرویس دهنده تا زمانی که تمامی thread ها آزاد نشده اند، قادر به پردازش درخواست ها نخواهد بود. اما در خصوص synchronous code، بسیاری از thread ها با اینکه هیچ کار یا عملیات خاصی را انجام نمی دهند، باز مشغول بوده و قابل دسترس نمی باشند. دلیلش این است که thread ها منتظر هستند که عملیات ورودی/خروجی به اتمام برسد. در رابطه با asynchronous code، هنگامی که فرایندی منتظر اتمام عملیات ورودی/خروجی می باشد، thread آن آزاد شده تا برای پردازش دیگر درخواست ها توسط سرور مورد استفاده قرار گیرد. در نتیجه، asynchronous code امکان و زمینه ی استفاده ی بهینه از منابع سرور را مهیا ساخته و همچنین سرور را قادر می سازد تا بدون هیچ گونه تاخیر ترافیک بیشتری را مدیریت کند.
در نسخه های قدیمی تر .NET، کدنویسی و تست آن بسیار پیچیده، مستعد خطا بوده و همچنین خطایابی (debug) آن بسیار دشوار می باشد. در ویرایش 4.5 .NET کدنویسی، تست و اشکال زدایی آن به مراتب آسان تر می باشد، از این رو پیشنهاد می کنیم تا حد امکان کدهای ناهمزمان (asynchronous) بنویسید. اگرچه نوشتن کدهای ناهمزمان باعث ورود مقداری سربار (overhead) می شود، در مواقع کم ترافیک، افت کارایی بسیار ناچیز بوده و مشکل بزرگی رخ نمی دهد. این در حالی است که در شرایطی که ترافیک بالا است، افزایش بالقوه ی کارایی چشمگیر خواهد بود.


ایجاد controller ای به نام Department

یک Controller به نام Department مانند نمونه های قبلی ایجاد کنید، اما برای این نمونه checkbox، actions Use async controller را تیک دار نمایید.


آموزش MVC

بخش های رنگی شده در کد زیر، نشان می دهد چه چیزهایی به synchronous code متد Index افزوده شده که آن را ناهمزمان (asynchronous) می کند:


 
public async Task Index()
        {
            var departments = db.Departments.Include(d => d.Administrator);
            return View(await departments.ToListAsync());
        }

چهار تغییر به کد بالا اعمال شده که به query امکان می دهد به صورت ناهمزمان اجرا گردد:
1. متد مورد نظر با کلیدواژه ی asynch علامت گذاری شده که به مترجم یا کامپایلر می فهماند که باید callback هایی را برای بخش های بدنه ی متد ایجاد کرده و شی Task< actionresult>که برگردانده می شود را به صورت خودکار ایجاد کند.
2. نوع (type) بازگشتی از ActionResult به Task< actionresult>تبدیل شده است. نوع Task< t>نشانگر عملیات یا کارهای در حال انجام با نتیجه ی type T می باشد.
کلیدواژه ی await به فراخوانی web service اعمال شده است. کامپایلر با دیدن این کلیدواژه، در پشت پرده متد مورد نظر را به دو بخش تقسیم می کند. اولین بخش آن متد با عملیاتی که به صورت ناهمزمان راه اندازی (آغاز) شده پایان می یابد و اما دومین بخش آن در یک متد callback قرار داده می شود که پس از اتمام عملیات، فراخوانی می شود.
3. نسخه ی ناهمزمان (asynchronous) متد الحاقی (extension method) به نام ToList صدا زده شده است.
چرا دستور departments.ToList اصلاح شده اما دستور departments = db.Departments مورد تغییر قرار نگرفته است؟ باید گفت دلیلش این است که تنها آن دستوراتی که باعث می شوند query یا command به پایگاه داده ارسال شود، به صورت ناهمزمان اجرا می شوند. دستور departments = db.Departments یک query تنظیم می کند، اما query تا زمانی که متد ToList فراخوانی نشده، اجرا نمی شود. بنابراین تنها متد ToList به صورت ناهمزمان اجرا می شود.
از میان متدهای Details و همچنین توابع HttpGet Edit و Delete، متد Find است که باعث می شود query به پایگاه داده ارسال شود، از این رو متدی که به صورت ناهمزمان اجرا می شود، فقط متد Find است.


public async Task< actionresult> Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Department department = await db.Departments.FindAsync(id);
            if (department == null)
            {
                return HttpNotFound();
            }
            return View(department);
        }

در متدهای Create، HttpPost Edit و DeleteConfirmed، این فراخوانی متد SaveChanges است که سبب می شود یک دستور اجرا شود، نه دستورهایی نظیر db.Departments.Add(department) که تنها منجر به اصلاح موجودیت ها در حافظه می شوند.


 
public async Task Create(Department department)
{
    if (ModelState.IsValid)
    {
        db.Departments.Add(department);
    await db.SaveChangesAsync();
        return RedirectToAction("Index");
    }

Views\Department\Index.cshtml را باز کرده و template code را با کد زیر جایگزین کنید:


@model IEnumerable< contosouniversity.models.department>
@{
    ViewBag.Title = "Departments";
}

Departments

@Html.ActionLink("Create New", "Create")

@foreach (var item in Model) { }
@Html.DisplayNameFor(model => model.Name) @Html.DisplayNameFor(model => model.Budget) @Html.DisplayNameFor(model => model.StartDate) Administrator
@Html.DisplayFor(modelItem => item.Name) @Html.DisplayFor(modelItem => item.Budget) @Html.DisplayFor(modelItem => item.StartDate) @Html.DisplayFor(modelItem => item.Administrator.FullName) @Html.ActionLink("Edit", "Edit", new { id = item.DepartmentID }) | @Html.ActionLink("Details", "Details", new { id = item.DepartmentID }) | @Html.ActionLink("Delete", "Delete", new { id = item.DepartmentID })

این کد عنوان را از Index به Departments تغییر داده، اسم Administrator را به سمت راست انتقال می دهد و اسم کامل administrator را فراهم می کند.
در view های Edit، Details، Delete و Create عنوان (caption) فیلد InstructorID را به "Administrator" تغییر دهید، همان طوری که اسم فیلد department را در Course viewها به "Department" تغییر دادید.
در view های Create و Edit از کد زیر استفاده کنید:



در viewهای Create و Details کد زیر را بکار ببرید:


Administrator

برنامه را اجرا کرده و تب Departments را کلیک کنید.


آموزش MVC

همه چیز در این controller ها به طور مشابه عمل می کند، با این فرق که در این controller، تمامی queryها به صورت ناهمزمان (asynch) اجرا می شوند.
نکاتی که در استفاده از برنامه نویسی غیرموازی (asynch) با EF بایستی به آن توجه کرد:


  1. استفاده از thread ها با async code توصیه نمی شود. به عبارتی دیگر، نبایست چندین عملیات را به طور موازی با استفاده از نمونه ی (context instance) یکسان انجام داد.
  2. اگر می خواهید از مزایای بهبود کارایی async code استفاده ی بهینه داشته باشید، لازم است اطمینان حاصل کنید تمامی library package هایی که مورد استفاده قرار می دهید، در صورت فراخوانی متدهای EF ای که باعث ارسال query ها به پایگاه داده می شوند، از async code استفاده کنند.

استفاده از Stored Procedure ها جهت درج، بروز آوری و حذف

برخی از DBA ها (مدیران پایگاه داده) ترجیح می دهند از stored procedure ها (رویه های ذخیره شده) برای دسترسی به پایگاه داده استفاده کنند. در ویرایش های پیشین EF می توانستید داده های مورد نیاز را با بکارگیری stored procedure ها بازیابی کنید. این کار به وسیله ی اجرای یک query خام صورت می گرفت. اما این امکان وجود نداشت که به EF دستور داد با استفاده از stored procedure عملیات بروز رسانی را انجام دهد. در نسخه ی نوین EF (ویرایش 6)، به راحتی می توان Code First گونه ای پیکربندی کرد که از stored procedure ها استفاده کند.
1. در فایل DAL\SchoolContext.cs، کد هایلایت شده را به متد OnModelCreating اضافه کنید.


  
protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove();
            modelBuilder.Entity()
                .HasMany(c => c.Instructors).WithMany(i => i.Courses)
                .Map(t => t.MapLeftKey("CourseID")
                    .MapRightKey("InstructorID")
                    .ToTable("CourseInstructor"));
            modelBuilder.Entity().MapToStoredProcedures();
        }

این کد به EF دستور می دهد با استفاده از stored procedure ها، عملیات درج، بروز رسانی و حذف را بر روی موجودیت Department انجام دهد.
2. در Package Manage Console، دستور زیر را وارد کنید:


add-migration DepartmentSP

فایل Migrations\_DepartmentSP.cs را باز کرده تا کد موجود در متد Up را مشاهده کنید. این متد stored procedure های Insert، Update و Delete را ایجاد می کند:


                             public override void Up()
        {
            CreateStoredProcedure(
        "dbo.Department_Insert",
        p => new
        {
            Name = p.String(maxLength: 50),
            Budget = p.Decimal(precision: 19, scale: 4, storeType: "money"),
            StartDate = p.DateTime(),
            InstructorID = p.Int(),
        },
        body:
            @"INSERT [dbo].[Department]([Name], [Budget], [StartDate], [InstructorID])
              VALUES (@Name, @Budget, @StartDate, @InstructorID)
             
              DECLARE @DepartmentID int
              SELECT @DepartmentID = [DepartmentID]
              FROM [dbo].[Department]
              WHERE @@ROWCOUNT > 0 AND [DepartmentID] = scope_identity()
             
              SELECT t0.[DepartmentID]
              FROM [dbo].[Department] AS t0
              WHERE @@ROWCOUNT > 0 AND t0.[DepartmentID] = @DepartmentID"
    );
 
            CreateStoredProcedure(
        "dbo.Department_Update",
        p => new
        {
            DepartmentID = p.Int(),
            Name = p.String(maxLength: 50),
            Budget = p.Decimal(precision: 19, scale: 4, storeType: "money"),
            StartDate = p.DateTime(),
            InstructorID = p.Int(),
        },
        body:
            @"UPDATE [dbo].[Department]
              SET [Name] = @Name, [Budget] = @Budget, [StartDate] = @StartDate, [InstructorID] = @InstructorID
              WHERE ([DepartmentID] = @DepartmentID)"
    );
 
            CreateStoredProcedure(
        "dbo.Department_Delete",
        p => new
        {
            DepartmentID = p.Int(),
        },
        body:
            @"DELETE [dbo].[Department]
              WHERE ([DepartmentID] = @DepartmentID)"
    ); 
                            }

. در Package Manage Console، دستور زیر را وارد نمایید:
update-database
4. برنامه را در debug mode اجرا کرده، تب Departments را باز کنید، سپس Create New را کلیک نمایید.
5. اطلاعات لازم برای یک department جدید را وارد کرده و Create را کلیک نمایید.


آموزش MVC

6. در محیط Visual Studio، اگر به گزارشات (log) در پنجره ی Output توجه کنید، می بینید که یک stored procedure باعث درج یک سطر Department شده است.


آموزش MVC

Code First اسم های پیش فرض برای stored procedure ها ایجاد می کند. در صورت استفاده از یک پایگاه داده ی از پیش موجود، ممکن است لازم باشد اسم stored procedure ها را سفارشی تنظیم کنید تا بتوانید از آن stored procedure هایی که قبلا در پایگاه داده تعریف شده اند، استفاده نمایید.
اگر بخواهید کارهایی را که stored procedure های ایجاد شده قادر به انجام آن ها هستند، تنظیم نمایید، در آن صورت بایستی کد ارائه شده توسط scaffolding برای متد Up migrations را که آن stored procedure را ایجاد می کند، ویرایش کنید. در آن صورت تمام تغییرات ایجاد شده توسط شما، هر زمانی که آن migration اجرا می شود منعکس شده و همچنین هنگامی که migrations به صورت خودکار در production پس از نصب (deployment) اجرا می شود، به production database اعمال می گردد.
اگر می خواهید Stored procedure موجود را که قبلا در یک migration ایجاد شده، تغییر دهید، در آن صورت می بایست با استفاده از دستور Add-Migration یک migration خالی ایجاد کرده، سپس کدی بنویسید که متد AlterStoredProcedure را فراخوانی کند.


آنچه در این مبحث انجام شد:

در این درس با نوشتن کدی که به صورت ناهمزمان اجرا می شود، کارایی سرور را افزایش داده و همچنین با نحوه ی استفاده از stored procedure ها برای اجرای عملیات بروز آوری، درج و حذف آشنا شدید. در فصل بعدی خواهید آموخت زمانی که چند کاربر سعی می کنند سطری یکسان را همزمان ویرایش کنند، چگونه می توان از از دست رفت داده جلوگیری کرد.

1394/09/06 5654 2075
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...