Seed Data در Entity Framework Core – جلسه ۴۹

Seed Data with Entity Framework Core

در این جلسه قصد داریم روش Seed Data در Entity Framework Core و یا همان ثبت اطلاعات پیش‌ فرض در پایگاه داده را بررسی نماییم و به بررسی بروزرسانی مدل و پایگاه داده در Entity Framework Core بپردازیم. ضمنا به شما نشان خواهیم داد تا چگونه اقدام به حذف Migration اعمال شده بروی پایگاه داده در Entity Framework Core نمایید. ما برای درج اطلاعات پیش فرض در پایگاه داده توسط Entity Framework Core دو روش را بررسی میکنیم. روش اول استفاده از کلاس DB Context و روش دوم استفاده از یک کلاس افزوده (External Extension) میباشد.

Seed Data در Entity Framework Core توسط کلاس DB Context

برای درج اطلاعات پیش فرض در پایگاه داده، ابتدا باید متد OnModelCreating را درون کلاس DB Context رونویسی (override) نماییم.

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

        }

سپس با استفاده از شیئ ModelBuilder و متد HasData اقدام به مقدار دهی اولیه به موجودیت مورد نظر میکنیم.

        public static void Seed(this ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Category>().HasData(
                new Category
                {
                    ID = 1,
                    CategoryName = "Bill",
                    Description = "This categoroy is assigned for recording Bill cost",
                    Active = CategoryActiveOptions.Yes
                });
        }

در ادامه، جهت انتقال داده مورد نظر به پایگاه داده از فرمان Add-Migration استفاده میکنیم. در صورت ایجاد کلاس مربوطه بدون هر گونه خطا با استفاده از فرمان Update-Database میتوان داده مورد نظر را به پایگاه داده منتقل نمود.

استفاده از External Extension جهت درج اطلاعات پیش فرض در Entity Framework Core

در صورتی که بخواهیم کلاس DB Context تا حد ممکن دارای خوانایی بیشتری باشد، میتوانیم درج اطلاعات پیش فرض و دیگر تنظیمات متد OnModelCreating را در یک کلاس افزوده دیگر اعمال نماییم. برای این منظور ابتدا یک کلاس Static با نام مناسب درون پوشه Models ایجاد میکنیم.

namespace DailyCostWebApplication.Models
{
    public static class SeedExtension
    {

    }
}

سپس درون آن یک متد Static ایجاد میکنیم و یک شیئ شیئ از ModelBuilder به عنوان پارامتر ورودی برای آن تعریف میکنیم. سپس با استفاده از همان شیئ ModelBuilder و متد HasData همانگونه که قبلا اشاره شد اقدام به درج اطلاعات پیش فرض مینماییم.

    public static class SeedExtension
    {
        public static void Seed(this ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Category>().HasData(
                new Category
                {
                    ID = 1,
                    CategoryName = "Bill",
                    Description = "This categoroy is assigned for recording Bill cost",
                    Active = CategoryActiveOptions.Yes
                });
        }
    }

حال میتوانیم درون کلاس DB Context از این متد افزوده برای درج اطلاعات در پایگاه داده استفاده نماییم.

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Seed();
        }

برای انتقال اطلاعات به پایگاه داده، همانگونه که ذکر شد از فرامین Add-Migration و Update-Database استفاده میکنیم.

بروزرسانی مدل و پایگاه داده در Entity Framework Core

بطور کلی برای بروزرسانی تغییرات مدل بر روی پایگاه داده در EF Core میبایست از فرامین Add-Migration و Update-Database استفاده نماییم. در زمان اجرای فرمان Add-Migration در صورت عدم بروز خطا یک کلاس با نام Migration مورد نظر ایجاد میگردد که حاوی دو متد میباشد. همچنین فایل Snapshot که درون پوشه Migrations قرار دارد بر اساس آخرین تغییرات مدل بروز میگردد. دو متد Up و Down درون کلاس Migration وظیفه بروزرسانی تغییرات بروی پایگاه داده و یا برگرداندن تغییرات اعمال شده در فایل Snapshot را برعهده دارند.

در صورت اجرای فرمان Update-Database متد Up از کلاس Migration اجرا میگردد و تغییرات اعمال شده بروی پایگاه داده اعمال میگردد. همچنین در صورت اجرای فرمان Remove-Migration متد Down اجرا شده و تغییرت اعمال شده بروی کلاس Snapshot به حالت قبل بازگردانده میگردد.

نمونه یک کلاس Migration مربوط به اضافه نمودن یک فیلد به موجودیت Cost.

using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace DailyCostWebApplication.Migrations
{
    public partial class AddInvoiceImagePathtoCost : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AddColumn<string>(
                name: "InvoiceImagePath",
                table: "Costs",
                type: "nvarchar(max)",
                nullable: true);
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropColumn(
                name: "InvoiceImagePath",
                table: "Costs");
        }
    }
}

نمونه کلاس Snapshot مربوط به پروژه این دوره آموزشی.

// <auto-generated />
using System;
using DailyCostWebApplication.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;

#nullable disable

namespace DailyCostWebApplication.Migrations
{
    [DbContext(typeof(WebAppDBContext))]
    partial class WebAppDBContextModelSnapshot : ModelSnapshot
    {
        protected override void BuildModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("ProductVersion", "6.0.2")
                .HasAnnotation("Relational:MaxIdentifierLength", 128);

            SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);

            modelBuilder.Entity("DailyCostWebApplication.Models.Category", b =>
                {
                    b.Property<int>("ID")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("int");

                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"), 1L, 1);

                    b.Property<int>("Active")
                        .HasColumnType("int");

                    b.Property<string>("CategoryName")
                        .IsRequired()
                        .HasColumnType("nvarchar(max)");

                    b.Property<string>("Description")
                        .HasColumnType("nvarchar(max)");

                    b.HasKey("ID");

                    b.ToTable("Categories", (string)null);

                    b.HasData(
                        new
                        {
                            ID = 1,
                            Active = 0,
                            CategoryName = "Bill",
                            Description = "This categoroy is assigned for recording Bill cost"
                        },
                        new
                        {
                            ID = 2,
                            Active = 0,
                            CategoryName = "Gerocery",
                            Description = "This categoroy is assigned for recording Gerocery cost"
                        },
                        new
                        {
                            ID = 3,
                            Active = 0,
                            CategoryName = "Rent",
                            Description = "This categoroy is assigned for recording Rental cost"
                        });
                });

            modelBuilder.Entity("DailyCostWebApplication.Models.Cost", b =>
                {
                    b.Property<int>("ID")
                        .ValueGeneratedOnAdd()
                        .HasColumnType("int");

                    SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("ID"), 1L, 1);

                    b.Property<decimal>("Amount")
                        .HasColumnType("decimal(18,2)");

                    b.Property<int>("CategoryID")
                        .HasColumnType("int");

                    b.Property<string>("Comment")
                        .HasMaxLength(150)
                        .HasColumnType("nvarchar(150)");

                    b.Property<string>("InvoiceImagePath")
                        .HasColumnType("nvarchar(max)");

                    b.Property<int>("PaymentMethod")
                        .HasColumnType("int");

                    b.Property<DateTime>("RegisteredDate")
                        .HasColumnType("datetime2");

                    b.HasKey("ID");

                    b.HasIndex("CategoryID")
                        .IsUnique();

                    b.ToTable("Costs", (string)null);
                });

            modelBuilder.Entity("DailyCostWebApplication.Models.Cost", b =>
                {
                    b.HasOne("DailyCostWebApplication.Models.Category", "Category")
                        .WithOne("Cost")
                        .HasForeignKey("DailyCostWebApplication.Models.Cost", "CategoryID")
                        .OnDelete(DeleteBehavior.Cascade)
                        .IsRequired();

                    b.Navigation("Category");
                });

            modelBuilder.Entity("DailyCostWebApplication.Models.Category", b =>
                {
                    b.Navigation("Cost");
                });
#pragma warning restore 612, 618
        }
    }
}

با هر بار اجرای فرمان Remove-Migration به ترتیب آخرین Migration اعمال شده حذف میگردد.

در صورت بروزرسانی مدل و پایگاه داده امکان حذف Migration به صورت عادی وجود ندارد.

حذف Migration اعمال شده بروی پایگاه داده در Entity Framework Core

جهت حذف Migration اعمال شده بروی پایگاه داده در Entity Framework Core ابتدا میبایست تغییرات اعمال شده بروی پایگاه داده را برگردانیم. اگر به جداول ایجاد شده در پایگاه داده نگاه کنید، یک جدول با نام EFMigrationsHistory مشاهده خواهید کرد. این جدول در واقع محل نمایش و ذخیره سازی تاریخچه Migrationهای اعمال شده بروی پایگاه داده میباشد. در نتیجه برای حذف یک Migration اعمال شده بروی پایگاه داده ابتدا میبایست با فرمان Update-Database و نام Migration مورد نظر، تغییرات اعمال شده بروی پایگاه داده را حذف نماییم. سپس میتوانیم با فرمان Remove-Migration اقدام به حذف Migration مورد نظر نماییم.

در صورت نیاز به جزئیات بیشتر، میتوانید ویدئو آموزشی این جلسه را تماشا نمایید. همچنین برای آگاهی از جلسات بعدی این دوره آموزشی، ما را در اینستاگرام، تلگرام، یوتیوب و آپارات دنبال کنید. ضمنا لیست کامل جلسات در این قسمت در دسترس شما میباشد و سورس کد این جلسه را میتوانید از GitHub ما دانلود نمایید.

تماشای ویدیو در یوتیوب ما

دانلود اسلایدهای آموزشی این جلسه از اینجا

برچسب ها

0 0 رای ها
امتیازدهی به مقاله
اشتراک در
اطلاع از
guest
0 نظرات
بازخورد (Feedback) های اینلاین
مشاهده همه دیدگاه ها
0
افکار شما را دوست داریم، لطفا نظر دهید.x