fluent API در Code First

fluent API در Code First

بسم الله الرحمن الرحیم

fluent API

در MVC برای ایجاد روابط بین جداول می توانید از fluent API استفاده کنید، این روش برای کد نویسی و طراحی دیتابیس به روش Code First می باشد:

 

One-to–Zero-or-One (روابط یک به یک)

modelBuilder.Entity<OfficeAssignment>() 
    .HasKey(t => t.InstructorID); 

به رابطه بالا One-to–Zero گفته می شود زیرا شما فقط کلید اصلی جدول را مشخص کرده اید آن را به هیچ جدول دیگری ارتباط نداده اید.

modelBuilder.Entity<OfficeAssignment>() 
    .HasRequired(t => t.Instructor) 
    .WithOptional(t => t.OfficeAssignment);

در این رابطه ما یک رابطه One-to-One ایجاد کرده ایم. در این رابطه سمت OfficeAssignment اختیاری است.

بسم الله الرحمن الرحیم

fluent API

در MVC برای ایجاد روابط بین جداول می توانید از fluent API استفاده کنید، این روش برای کد نویسی و طراحی دیتابیس به روش Code First می باشد:

 

One-to–Zero-or-One (روابط یک به یک)

modelBuilder.Entity<OfficeAssignment>() 
    .HasKey(t => t.InstructorID); 

به رابطه بالا One-to–Zero گفته می شود زیرا شما فقط کلید اصلی جدول را مشخص کرده اید آن را به هیچ جدول دیگری ارتباط نداده اید.

modelBuilder.Entity<OfficeAssignment>() 
    .HasRequired(t => t.Instructor) 
    .WithOptional(t => t.OfficeAssignment);

در این رابطه ما یک رابطه One-to-One ایجاد کرده ایم. در این رابطه سمت OfficeAssignment اختیاری است.

برای اجباری کردن هر دو سمت در یک رابطه یک به یک می توانید به صورت زیر عمل کنید:

modelBuilder.Entity<OfficeAssignment>() 
    .HasKey(t => t.InstructorID); 
 
modelBuilder.Entity<Instructor>() 
    .HasRequired(t => t.OfficeAssignment) 
    .WithRequiredPrincipal(t => t.Instructor);

 

Many-to-Many (روابط چند به چند)

modelBuilder.Entity<Course>() 
    .HasMany(t => t.Instructors) 
    .WithMany(t => t.Courses)

 

اگر شما بخواهید نام جداول و columns هایی که می خواهید بین آنها رابطه ایجاد کنید را مشخص کنید و اطلاعات بیشتری را تنظیم کنید می توانید از روش زیر استفاده کنید:

modelBuilder.Entity<Course>() 
    .HasMany(t => t.Instructors) 
    .WithMany(t => t.Courses) 
    .Map(m => 
    { 
        m.ToTable("CourseInstructor"); 
        m.MapLeftKey("CourseID"); 
        m.MapRightKey("InstructorID"); 
    });

Cascade Delete

شما به وسیله متد WillCascadeOnDelete می توانید cascade delete را بر روی Relation خود ایجاد کنید، اگر کلید خارجی شما در دیتابیس nullable نباشد Code First بر روی رابطه شما cascade delete را اجرا می کند اما اگر کلید خارجی شما nullable باشد Code First

بر روی رابطه شما cascade delete را اجرا نمی کند و هنگام حذف کلید اصلی کلید خارجی با مقدار null مقدار دهی می شود، این همان حال SET NULL  در SQL Server است.

 

برای حذف cascade delete می توانید از کد زیر استفاده کنید:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>()
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>()

کد زیر یک رابطه ایجاد می کند و cascade delete را نیز فعال می کند:

modelBuilder.Entity<Course>() 
    .HasRequired(t => t.Department) 
    .WithMany(t => t.Courses) 
    .HasForeignKey(d => d.DepartmentID) 
    .WillCascadeOnDelete(true);

Configuring a Composite Foreign Key

شاید شما دارای یک کلید اصلی ترکیبی باشید، مثلا کلید شما در جدول Department، از دو فیلد تشکیل شده است یکی پراپرتی Name و دیگری پراپرتی DepartmentID برای معرفی این دو پراپرتی به عنوان کلید اصلی در جدول، شمات باید به صورت زیر عمل کنید:

/ Composite primary key */
modelBuilder.Entity<Department>() 
.HasKey(d => new { d.DepartmentID, d.Name }); 
 
/ Composite foreign key */
modelBuilder.Entity<Course>()  
    .HasRequired(c => c.Department)  
    .WithMany(d => d.Courses) 
    .HasForeignKey(d => new { d.DepartmentID, d.DepartmentName });

 

Renaming a Foreign Key That Is Not Defined in the Model

اگر شما نامی را برای کلید خارجی استفاده می کنید که در مل شما نیست اما در جدول شما در دیتابس وجود دارد می توانید به صورت زیر عمل کنید:

modelBuilder.Entity<Course>() 
    .HasRequired(c => c.Department) 
    .WithMany(t => t.Courses) 
    .Map(m => m.MapKey("ChangedDepartmentID"));

 

Configuring a Foreign Key Name That Does Not Follow the Code First Convention

اگر کلید خارجی شما در کلاس Course دارای نام SomeDepartmentID به جای DepartmentID باشد، شما باید این نام را دقیقا مشخص کنید، با استفاده از کد زیر می توانید این کار را انجام دهید:

modelBuilder.Entity<Course>() 
         .HasRequired(c => c.Department) 
         .WithMany(d => d.Courses) 
         .HasForeignKey(c => c.SomeDepartmentID);

 

Model Used in Samples

یک مثال کامل برای شما:

using System.Data.Entity; 
using System.Data.Entity.ModelConfiguration.Conventions; 
/* add a reference to System.ComponentModel.DataAnnotations DLL */
using System.ComponentModel.DataAnnotations; 
using System.Collections.Generic; 
using System; 
 
public class SchoolEntities : DbContext 
{ 
    public DbSet<Course> Courses { get; set; } 
    public DbSet<Department> Departments { get; set; } 
    public DbSet<Instructor> Instructors { get; set; } 
    public DbSet<OfficeAssignment> OfficeAssignments { get; set; } 
 
    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
        /* Configure Code First to ignore PluralizingTableName convention */
        /* If you keep this convention then the generated tables will have pluralized names. */
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
    } 
} 
 
public class Department 
{ 
    public Department() 
    { 
        this.Courses = new HashSet<Course>(); 
    } 
    /* Primary key */
    public int DepartmentID { get; set; } 
    public string Name { get; set; } 
    public decimal Budget { get; set; } 
    public System.DateTime StartDate { get; set; } 
    public int? Administrator { get; set; } 
 
    /* Navigation property */
    public virtual ICollection<Course> Courses { get; private set; } 
} 
 
public class Course 
{ 
    public Course() 
    { 
        this.Instructors = new HashSet<Instructor>(); 
    } 
    /* Primary key */
    public int CourseID { get; set; } 
 
    public string Title { get; set; } 
    public int Credits { get; set; } 
 
    /* Foreign key */
    public int DepartmentID { get; set; } 
 
    /* Navigation properties */
    public virtual Department Department { get; set; } 
    public virtual ICollection<Instructor> Instructors { get; private set; } 
} 
 
public partial class OnlineCourse : Course 
{ 
    public string URL { get; set; } 
} 
 
public partial class OnsiteCourse : Course 
{ 
    public OnsiteCourse() 
    { 
        Details = new Details(); 
    } 
 
    public Details Details { get; set; } 
} 
 
public class Details 
{ 
    public System.DateTime Time { get; set; } 
    public string Location { get; set; } 
    public string Days { get; set; } 
} 
     
public class Instructor 
{ 
    public Instructor() 
    { 
        this.Courses = new List<Course>(); 
    } 
 
    /* Primary key */
    public int InstructorID { get; set; } 
    public string LastName { get; set; } 
    public string FirstName { get; set; } 
    public System.DateTime HireDate { get; set; } 
 
    /* Navigation properties */
    public virtual ICollection<Course> Courses { get; private set; } 
} 
 
public class OfficeAssignment 
{ 
    /* Specifying InstructorID as a primary */
    [Key()] 
    public Int32 InstructorID { get; set; } 
 
    public string Location { get; set; } 
 
    /* When the Entity Framework sees Timestamp attribute */
    /* it configures ConcurrencyCheck and DatabaseGeneratedPattern=Computed. */
    [Timestamp] 
    public Byte[] Timestamp { get; set; } 
 
    /* Navigation property */
    public virtual Instructor Instructor { get; set; } 
}

نظرات

  • Hannah Martinez
    آرزو
    دو شنبه 11 دی 1278 - 0:00

    سلام 

    وقتتون بخیر.
    ممنون از مقاله های عالی تون.
    من 1 پروژه دارم با 3 کلاس Person، Student، Employee که Student، Employee هر دو با Person یک ارتباط یک به یک دارند.
    موضوع از این قرار که شخصی که ثبت نام می کنه اگر دانشجو باشه یک سری اطلاعات اضافه مثل نام دانشگاه و ... اضافه می کنه.
    اگر هم کارمند باشه همینطور من با MVC5 و EF CodeFirst اینکار انجام دادم ولی مشکل اینجاست که اگر شخص1 کارمند باشه توی پایگاه داده تو جدول دانشجو یک سطر با ID=1 ولی نام دانشگاه Null ایجاد می کنه و اگر هم دانشجو باشه تو جدول کارمند یک سطر Null رد می کنه.
    نمیخوام اینطور بشه میشه بزرگواری کنید و راهنمایی کنید؟

  • Hannah Martinez
    فاطمه
    دو شنبه 11 دی 1278 - 0:00

    واقعا ممنون.

    خیلی خوب بود

  • Hannah Martinez
    حسین
    دو شنبه 11 دی 1278 - 0:00

    ممنون از مطلب مفیدی که نوشتید

    • Judith Bell
      پاسخ
      اسماعیلشیدایی
      دو شنبه 11 دی 1278 - 0:00

      خواهش می کنم

  • Hannah Martinez
    meysam
    دو شنبه 11 دی 1278 - 0:00

    ممنون از شما بابت مطلب مفیدتون.

    • Judith Bell
      پاسخ
      اسماعیلشیدایی
      دو شنبه 11 دی 1278 - 0:00

      خواهش می کنم

نظرات یا سوالات خودرا با ما درمیان بگذارید

0912 097 5516 :شماره تماس
0713 625 1757 :شماره تماس