EF 6 Code-First系列文章目录:数据库
当两个实体之间不止一种关系的时候,能够使用InverseProperty特性,为了理解InverseProperty特性咱们来作一个例子:
1.建立一个控制台应用程序,安装好EF:
2.建立Course类:app
public class Course
{
public int CourseId { get; set; }
public string CourseName { get; set; }
public string Description { get; set; }
public Teacher OnlineTeacher { get; set; }
}
3.建立Teacher类:ide
public class Teacher
{
public int TeacherId { get; set; }
public string Name { get; set; }
public ICollection<Course> OnlineCourses { get; set; }
}
上面的代码例子中,Course和Teacher实体之间是一对多的关系,一个Teacher能够教不少的Online Course。
3.建立上下文类:测试
public class EFDbContext:DbContext
{
public EFDbContext() : base("name=Constr") { }
public DbSet<Course> Courses { get; set; }
public DbSet<Teacher> Teachers { get; set; }
}
4.SQL连接字符串:ui
<!--SQL连接字符串-->
<connectionStrings>
<add name="Constr" connectionString="Server=.;Database=EFAnnotationInversePropertyDB;uid=sa;pwd=Password_1" providerName="System.Data.SqlClient"/>
</connectionStrings>
5.测试代码:spa
class Program
{
static void Main(string[] args) {
using (var db = new EFDbContext())
{
List<Course> lstModel = db.Courses.ToList();
}
Console.WriteLine("success");
Console.ReadKey();
}
}
6.运行程序:
能够看到,根据默认的约定,生成的数据库以下:
.net
如今假设Course和Teacher实体之间,还有一个一对多的关系:
Course类:翻译
public class Course
{
public int CourseId { get; set; }
public string CourseName { get; set; }
public string Description { get; set; }
public Teacher OnlineTeacher { get; set; }
public Teacher ClassRoomTeacher { get; set; }
}
Teacher类:3d
public class Teacher
{
public int TeacherId { get; set; }
public string Name { get; set; }
public ICollection<Course> OnlineCourses { get; set; }
public ICollection<Course> ClassRoomCourses { get; set; }
}
在上面代码例子中,Course和Teacher实体有两个一对多的关系。一门课程能够被一个Online Teacher教,也能够被一个class-room Teacher教。一样一个教师能够教多个Online Course,也能够教多个class-room Course.
删掉以前生成的数据库后,咱们运行一下程序:
看看生成的数据库:
看到,EF为咱们在Course表中,生成了4个外键。为了解决这个问题,咱们使用InverseProperty特性。修改一下Teacher类的代码:
Teacher类:
public class Teacher
{
public int TeacherId { get; set; }
public string Name { get; set; }
[InverseProperty("OnlineTeacher")]
public ICollection<Course> OnlineCourses { get; set; }
[InverseProperty("ClassRoomTeacher")]
public ICollection<Course> ClassRoomCourses { get; set; }
}
Course类:
public class Course
{
public int CourseId { get; set; }
public string CourseName { get; set; }
public string Description { get; set; }
public Teacher OnlineTeacher { get; set; }
public Teacher ClassRoomTeacher { get; set; }
}
在上面的例子中,InverseProperty特性应用在两个集合类型的导航属性OnlineCourses和ClassRoomCourses上,而后指定它们在Course实体中的相关联的导航属性,因此如今EF就能分辨出来相应的外键。EF 6将建立两个外键:OnlineTeacher_TeacherId
和ClassRoomTeacher_TeacherId
。对于EF Core将会建立OnlineTeacherTeacherId
和ClassRoomTeacherTeacherId
两个外键。
而后在删除数据库,从新运行一下程序:
看一下生成的数据库:
能够看到如今生成的数据库就是正确的了。
进一步配置,你能够使用ForeignKey特性来配置外键名称:
Course类:
public class Course
{
public int CourseId { get; set; }
public string CourseName { get; set; }
public string Description { get; set; }
[ForeignKey("OnlineTeacher")]
public int OnlineTeacherId { get; set; }
public Teacher OnlineTeacher { get; set; }
[ForeignKey("ClassRoomTeacher")]
public int ClassRoomTeacherId { get; set; }
public Teacher ClassRoomTeacher { get; set; }
}
Teacher类:
public class Teacher
{
public int TeacherId { get; set; }
public string Name { get; set; }
[InverseProperty("OnlineTeacher")]
public ICollection<Course> OnlineCourses { get; set; }
[InverseProperty("ClassRoomTeacher")]
public ICollection<Course> ClassRoomCourses { get; set; }
}
上面代码中,咱们在Corse类中添加两个属性列,配置外键,如今删除数据库,从新运行一下:
看到报错了,咱们修改一下Course类:
Course类最终代码:
public class Course
{
public int CourseId { get; set; }
public string CourseName { get; set; }
public string Description { get; set; }
[ForeignKey("OnlineTeacher")]
public int? OnlineTeacherId { get; set; }
public Teacher OnlineTeacher { get; set; }
[ForeignKey("ClassRoomTeacher")]
public int? ClassRoomTeacherId { get; set; }
public Teacher ClassRoomTeacher { get; set; }
}
从新运行程序:能够看到成功了。
咱们看看最终生成的数据库:
能够看到生成的外键列就是咱们本身自定义的名称了。 综上所述:当两个实体间有多个关系的时候,你能够使用InverseProperty 特性和ForeignKey 特性来配置实体。