相关链接:Configuring Relationships with the Fluent API
Configuring a Required-to-Optional Relationship (One-to-Zero-or-One 1…0,1)
以下示例,表示1…0,1的关系。OfficeAssignment表有一个属性InstructorID,它是一个主键也是一个外键。
HasKey方法用于配置主键。
// Configure the primary key for the OfficeAssignment modelBuilder.Entity<OfficeAssignment>() .HasKey(t => t.InstructorID); // Map one-to-zero or one relationship modelBuilder.Entity<OfficeAssignment>() .HasRequired(t => t.Instructor) .WithOptional(t => t.OfficeAssignment);
Configuring a Relationship Where Both Ends Are Required (One-to-One)
// Configure the primary key for the OfficeAssignment modelBuilder.Entity<OfficeAssignment>() .HasKey(t => t.InstructorID); modelBuilder.Entity<Instructor>() .HasRequired(t => t.OfficeAssignment) .WithRequiredPrincipal(t => t.Instructor);
Configuring a Many-to-Many Relationship
modelBuilder.Entity<Course>() .HasMany(t => t.Instructors) .WithMany(t => t.Courses)
modelBuilder.Entity<Course>() .HasMany(t => t.Instructors) .WithMany(t => t.Courses) .Map(m => { m.ToTable("CourseInstructor"); m.MapLeftKey("CourseID"); m.MapRightKey("InstructorID"); });
Configuring a Relationship with One Navigation Property
// Configure the primary Key for the OfficeAssignment modelBuilder.Entity<OfficeAssignment>() .HasKey(t => t.InstructorID); modelBuilder.Entity<Instructor>() .HasRequired(t => t.OfficeAssignment) .WithRequiredPrincipal();
Enabling Cascade Delete
modelBuilder.Entity<Course>() .HasRequired(t => t.Department) .WithMany(t => t.Courses) .HasForeignKey(d => d.DepartmentID) .WillCascadeOnDelete(false);
Configuring a Composite Foreign Key
// 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
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; } }