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 اختیاری است.
برای اجباری کردن هر دو سمت در یک رابطه یک به یک می توانید به صورت زیر عمل کنید:
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; }
}
نظرات (۳)
خواهش می کنم
خواهش می کنم