博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Entity Framework Code First (五)Fluent API - 配置关系
阅读量:6894 次
发布时间:2019-06-27

本文共 8010 字,大约阅读时间需要 26 分钟。

  上一篇文章我们讲解了如何用 Fluent API 来配置/映射属性和类型,本文将把重点放在其是如何配置关系的。

  文中所使用代码如下

public class Student    {        public int ID { get; set; }        public string Name { get; set; }        public DateTime EnrollmentDate { get; set; }        // Navigation properties        public virtual Address Address { get; set; }        public virtual OtherInfo OtherInfo { get; set; }        public virtual ICollection
Enrollments { get; set; } } public class Department { public Department() { this.Courses = new HashSet
(); } // 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
Courses { get; private set; } } public class Course { public int CourseID { get; set; } public string Title { get; set; } public int Credits { get; set; } // Foreign key public int DepartmentID { get; set; } public string DepartmentName { get; set; } public int SomeDepartmentID { get; set; } // Navigation properties public virtual Department Department { get; set; } public virtual ICollection
Enrollments { get; set; } public virtual ICollection
Instructors { get; set; } } public class Instructor { public int InstructorID { get; set; } public string Name { get; set; } public DateTime HireDate { get; set; } // Navigation properties public virtual ICollection
Courses { get; set; } } public class Enrollment { public int EnrollmentID { get; set; } public int CourseID { get; set; } public int StudentID { get; set; } // Navigation property public virtual Course Course { get; set; } public virtual Student Student { get; set; } } public class Address { public int AddressId { get; set; } public string HomeAddress { get; set; } public string LiveAddress { get; set; } // Navigation property public virtual Student Student { get; set; } } public class OtherInfo { public int Id { get; set; } public string HomeAddress { get; set; } public string MailAddress { get; set; } public string PhoneNumber { get; set; } public string StudentID { get; set; } // Navigation property public virtual Student Student { get; set; } }
View Code

 

EntityTypeConfiguration<TEntityType>

  上面是泛型类的部分方法截图,一般我们通过 Code First Fluent API 来配置实体间的关系时都是从此泛型类的实例开始,此泛型类为我们提供了大部分的关系处理方法,如必须的 HasRequired ,可选的 HasOptional ,多个的 HasMany .

  上面所有方法(除了 HasMany, HasOptional, HasRequired )的返回值都是泛型类 EntityTypeConfiguration<TEntityType> 的实例本身,这给链式操作提供了极大地方便.

  HasRequired, HasOptional, HasMany 这三个方法的参数都是一个 lambda expression, 只不过前两个用于表示实体关系(Relationship)间的导航属性(navigation property),后一个则是导航属性的集合(Collection

  HasRequired, HasOptional, HasMany 这三个方法的返回值都是可以继续进行配置的泛型类实例,虽然名称不同,方法名也略有不同,但方法主体所体现的思想是一致的

RequiredNavigationPropertyConfiguration<TEntityType, TTargetEntityType>

OptionalNavigationPropertyConfiguration<TEntityType, TTargetEntityType>

ManyNavigationPropertyConfiguration<TEntityType, TTargetEntityType>

  三个泛型类都有类似于如下三个方法 WithRequired, WithOptional, WithMany, 这三个方法都提供了重载的无参版本,有参方法的参数也都是一个 lambda expression, 前两个用于表示实体关系(Relationship)间的导航属性(navigation property),后一个则是导航属性的集合(Collection

  接下来,你可以使用方法 HasForeignKey 继续配置外键属性,方法的参数仍然是一个 lambda expression, 只不过代表一个属性

DependentNavigationPropertyConfiguration<TDependentEntityType>

public CascadableNavigationPropertyConfiguration HasForeignKey
(Expression
> foreignKeyExpression);

  其它两个类主要包含方法 Map ,如下

ForeignKeyNavigationPropertyConfiguration

public CascadableNavigationPropertyConfiguration Map(Action
configurationAction);

ManyToManyNavigationPropertyConfiguration<TEntityType, TTargetEntityType>

public ManyToManyNavigationPropertyConfiguration
Map(Action
configurationAction);public ManyToManyNavigationPropertyConfiguration
MapToStoredProcedures();public ManyToManyNavigationPropertyConfiguration
MapToStoredProcedures(Action
> modificationStoredProcedureMappingConfigurationAction);

  我们可以继续在返回的实例上进行配置

CascadableNavigationPropertyConfiguration

public void WillCascadeOnDelete();public void WillCascadeOnDelete(bool value);

  我们看到了级联删除

 

Configuring Relationships

1:1,0 - Configuring a Required-to-Optional Relationship (One-to–Zero-or-One)

  一个学生可以有一个或没有其它信息(包括邮件地址、手机号等)

// Map one-to-zero or one relationshipmodelBuilder.Entity
() .HasRequired(t => t.Student) .WithOptional(t => t.OtherInfo);

1:1 - Configuring a Relationship Where Both Ends Are Required (One-to-One)

  一个学生肯定有一个地址信息(包含家庭住址、居住地址)

// Map one-to-one relationshipmodelBuilder.Entity
() .HasRequired(t => t.Student) .WithRequiredPrincipal(t => t.Address);

1:N - Configuring a Required-to-Many Relationship (One-to-Many)

  一个学生可以参加多门课程

// Map one-to-many relationshipmodelBuilder.Entity
() .HasMany(t => t.Enrollments) .WithRequired(t => t.Student);

N:N - Configuring a Many-to-Many Relationship (Many-to-Many)

  一个老师可以教授多门课程,一门课程也可以由多名老师教授

// Map one-to-many relationshipmodelBuilder.Entity
() .HasMany(t => t.Instructors) .WithMany(t => t.Courses);

  你还可以进一步指定中间连接表(数据库将会创建中间连接表)

// Map one-to-many relationshipmodelBuilder.Entity
() .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 - 基于导航属性配置关系

  如果关系是单向的,即两个实体间只在一个实体上定义导航属性。Code First Conventions 能够自动推断这种关系为 one-to-many .

  例如你想在 Student 和 Address 两个实体间建立 one-to-one 关系,而且只在 Address 实体上包含导航属性,此时你就需要用 Code First Fluent API 配置这种关系

// Map one-to-one relationshipmodelBuilder.Entity
() .HasRequired(t => t.Student) .WithRequiredPrincipal();

WillCascadeOnDelete - Enabling Cascade Delete (级联删除)

  你可以使用 WillCascadeOnDelete 来级联删除关系,如果从属主体上的外键是 not nullable, 那么 Code First 将设置级联删除,否则将不会设置级联删除,而只是仅仅把外键设置成 null

   在 Code First Conventions 下是这样移除级联删除的

modelBuilder.Conventions.Remove
()modelBuilder.Conventions.Remove
()

  Code First Fluent API 的方式如下

// Cascade DeletemodelBuilder.Entity
() .HasRequired(t => t.Department) .WithMany(t => t.Courses) .HasForeignKey(d => d.DepartmentID) .WillCascadeOnDelete(false);

Configuring a Composite Foreign Key - 配置组合外键

  如果设置 Department 的主键为组合主键 DepartmentID, Name,则可以通过 Fluent API 为 Course 指定组合外键

// Composite primary keymodelBuilder.Entity
() .HasKey(d => new { d.DepartmentID, d.Name });// Composite foreign keymodelBuilder.Entity
() .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 - 重命名外键

  可以重命名外键名

// Renaming a Foreign Key That Is Not Defined in the ModelmodelBuilder.Entity
() .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

  如果从属实体上的外键属性名不符合 Code First Conventions 的规范,意即从属实体上没有外键,你可以通过如下方式来指定

// Configuring a Foreign Key Name That Does Not Follow the Code First ConventionmodelBuilder.Entity
() .HasRequired(c => c.Department) .WithMany(d => d.Courses) .HasForeignKey(c => c.SomeDepartmentID);

原文链接:

摘抄:http://www.cnblogs.com/panchunting/p/entity-framework-code-first-fluent-api-configuring-relationships.html
 
 
你可能感兴趣的文章
spool+sql拼接实现导出结果集为csv格式文件
查看>>
【19】Python工资管理系统
查看>>
HAProxy+Keepalived实现Web服务器负载均衡
查看>>
配置Linux主机SSH无密码访问
查看>>
servlet接收乱码处理方案
查看>>
自动化运维之Ansible的安装与简单入门命令
查看>>
mysql互为主从的环境,更新一条语句同时提交,为什么会出现数据不一致?
查看>>
Vmware软件安装精讲
查看>>
mysql双主模式
查看>>
rpm 安装lamp
查看>>
区块链真的有这么厉害吗?--初识区块链后的感想(一)
查看>>
mongodb Profiling 通过慢查询日志分析查询慢的原因 相应优化
查看>>
Memcached管理与监控工具 MemAdmin
查看>>
mysql 主从复制读写分离
查看>>
在百花之中干掉一个杂草连接...
查看>>
HTML文档基本格式
查看>>
for 循环的关键字 break和continue
查看>>
Map集合的四种遍历方式
查看>>
MySQL监控项一些指标
查看>>
Thinkpad T430s NVS5400M Ubuntu 12.04安装
查看>>