int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade? Grade { get; set; }
public virtual Course Course { get; set; }
public virtual Student Student { get; set; }
}
}
}
其中属性EnrollmentID 是primary key,Enrollment实体使用了classnameID模式而不是直接使用ID。通常情况下你应该选择其中的一种模式来使用,并在项目中统一使用这种模式来命名。这里同时使用了者两种模式只是做演示用,但是在数据模型中直接使用ID可以更容易的实现继承机制。
属性Grade是枚举类型,问号表示Grade可以是nullable。
属性StudentID是一个外键( foreign key),相对应的导航属性是Student实体,一个Enrollment实体只关联一个Student实体,而不像Student.Enrollments导航属性可以关联多个Enrollment实体。
同样CourseID也是外键,相关的导航属性是Course,同样一个Enrollment实体只关联一个Course实体。
如果属性被命名为
,Entity Framework会自动将其定义为外键。
Course 实体

![\]()
在Models目录下新建Course.cs类,添加代码:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;
namespace ContosoUniversity.Models
{
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public virtual ICollection
Enrollments { get; set; }
}
}
属性Enrollments是导航属性,Course和Enrollment是一对多的关系。
7.创建数据库上下文(database context)
在一个数据模型中负责调用Entity Framework功能类是数据库上下文类,可以通过派生System.Data.Entity.DbContext来创建这个类。你可以指定数据模型中要包含有哪些实体,你也可以自定义某些Entity Framework的行为,在此项目中数据库上下文为“SchoolContext”。
在项目中新建文件夹并命名为DAL (for Data Access Layer),在此文件件中新建类并命名为SchoolContext.cs,添加以下代码:
using ContosoUniversity.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
using System.Web;
namespace ContosoUniversity.DAL
{
public class SchoolContext:DbContext
{
public SchoolContext(): base("SchoolContext")
{
}
public DbSet
Students { get; set; }
public DbSet
Enrollments { get; set; } public DbSet
Courses { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove
(); } } }
指定实体集
这段代码为每个实体集指定了一个DbSet属性,在 Entity Framework中每一个实体集对应于一个数据库表,每一个实体对应于表中的一行。你可以省略DbSet
和DbSet
,此时项目仍能正常运行。因为Entity Framework会自动将他们包含进来,因为Student实体引用了Enrollment实体,并且Enrollment实体引用了Course实体。
指定连接字符串
这里通过在web.config中添加连接字符串并将其传递给构造函数,你也可以直接将连接字符串本身作为参数传递给构造函数。如果你没有指定连接字符串的话,Entity Framework就会将类名作为连接字符串的名字。
public SchoolContext() : base("SchoolContext")
{
}
指定表名
在OnModelCreating方法中modelBuilder.Conventions.Remove语句可以防止生成的表名为复数。如果不这样做的话,数据库中生成的表名将为Students, Courses和Enrollments,这里对于表名使用复数或单数没有明确的要求,对于开发者来说可以根据自己的喜好自行选择。
8.通过Entity Framework使用测试数据初始化数据库
当应用程序运行时Entity Framework会自动创建数据库,如果数据库已经存在,Entity Framework会将其删除后重新建立。当然你也可以指定是在应用程序每次运行时还是数据模型和数据库结构不一致时执行创建数据库命令。Entity Framework会自动调用Seed方法并使用测试数据初始化数据库。
默认情况下只有数据库不存在时才由Entity Framework创建,如果数据库已经存在或者数据模型发生变化时,Entity Framework会抛出异常。在生产环境中是不建议这样做的,因为这样会丢掉数据库所有的数据。
在DAL文件夹,新建一个名为SchoolInitializer.cs的类,并添加代码:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace ContosoUniversity.DAL
{
public class SchoolInitializer : DropCreateDatabaseIfModelChanges
{
protected override void Seed(SchoolContext context)
{
var students = new List
{ new Student{Fi