创建EF数据模型
最后的应用程序,看上去就像下边这样:
创建数据模型,你将从以下三个类开始:
在Models文件夹,新建以下类:
1 using System; 2 using System.Collections.Generic; 3 4 namespace ContosoUniversity.Models 5 { 6 public class Student 7 { 8 public int ID { get; set; } 9 public string LastName { get; set; } 10 public string FirstMidName { get; set; } 11 public DateTime EnrollmentDate { get; set; } 12 13 public virtual ICollection<Enrollment> Enrollments { get; set; } 14 } 15 }
1 namespace ContosoUniversity.Models 2 { 3 public enum Grade 4 { 5 A, B, C, D, F 6 } 7 8 public class Enrollment 9 { 10 public int EnrollmentID { get; set; } 11 public int CourseID { get; set; } 12 public int StudentID { get; set; } 13 public Grade? Grade { get; set; } 14 15 public virtual Course Course { get; set; } 16 public virtual Student Student { get; set; } 17 } 18 }
1 using System.Collections.Generic; 2 using System.ComponentModel.DataAnnotations.Schema; 3 4 namespace ContosoUniversity.Models 5 { 6 public class Course 7 { 8 [DatabaseGenerated(DatabaseGeneratedOption.None)] 9 public int CourseID { get; set; } 10 public string Title { get; set; } 11 public int Credits { get; set; } 12 13 public virtual ICollection<Enrollment> Enrollments { get; set; } 14 } 15 }
创建数据库上下文
新建文件夹DAL,加入以下类:
using ContosoUniversity.Models; using System.Data.Entity; using System.Data.Entity.ModelConfiguration.Conventions; namespace ContosoUniversity.DAL { public class SchoolContext : DbContext { public SchoolContext() : base("SchoolContext") { } public DbSet<Student> Students { get; set; } public DbSet<Enrollment> Enrollments { get; set; } public DbSet<Course> Courses { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Entity; using ContosoUniversity.Models; namespace ContosoUniversity.DAL { public class SchoolInitializer : System.Data.Entity. DropCreateDatabaseIfModelChanges<SchoolContext> { protected override void Seed(SchoolContext context) { var students = new List<Student> { new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01")}, new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2002-09-01")}, new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2003-09-01")}, new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2002-09-01")}, new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2002-09-01")}, new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2001-09-01")}, new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2003-09-01")}, new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2005-09-01")} }; students.ForEach(s => context.Students.Add(s)); context.SaveChanges(); var courses = new List<Course> { new Course{CourseID=1050,Title="Chemistry",Credits=3,}, new Course{CourseID=4022,Title="Microeconomics",Credits=3,}, new Course{CourseID=4041,Title="Macroeconomics",Credits=3,}, new Course{CourseID=1045,Title="Calculus",Credits=4,}, new Course{CourseID=3141,Title="Trigonometry",Credits=4,}, new Course{CourseID=2021,Title="Composition",Credits=3,}, new Course{CourseID=2042,Title="Literature",Credits=4,} }; courses.ForEach(s => context.Courses.Add(s)); context.SaveChanges(); var enrollments = new List<Enrollment> { new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A}, new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C}, new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B}, new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B}, new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F}, new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F}, new Enrollment{StudentID=3,CourseID=1050}, new Enrollment{StudentID=4,CourseID=1050,}, new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F}, new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C}, new Enrollment{StudentID=6,CourseID=1045}, new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A}, }; enrollments.ForEach(s => context.Enrollments.Add(s)); context.SaveChanges(); } } }
向web.config中添加一个元素来告诉实体框架你将使用初始化类,如下:
<entityFramework> <contexts> <context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity"> <databaseInitializer type="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity" /> </context> </contexts> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="v11.0" /> </parameters> </defaultConnectionFactory> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> </providers> </entityFramework>
context的Type属性指定了上下文的类名。你应当使用完整的类名和程序集名。同样databaseInitializer的Type指定了初始化类的名称。(如果你不想使用EF初始化,你可以在上下文元素中设置disableDatabaseInitialization="true")。
作为一种在web.config中设置初始值设定项的替代方法,你可以通过在Global.asax.cs中Application_Start方法中增加Database.SetInitializer语句来实现同样的功能。
现在应用程序已经设置为在程序首次运行时,对模型和数据库中的表进行比较,如果有区别,应用程序删除并重新创建该数据库。
注意:当你将应用程序部署到生产环境中时,你必须删除或禁用数据库重新创建代码,后面的教程会演示这一点。
使用SQL Server Express LocalDB数据库
LocalDB是SQL Server Express的一个轻量版本,非常适合用来进行本地测试,但不建议在生产中使用。
打开应用程序的web.config文件,添加数据库连接字符串,如下面的例子:
1 <connectionStrings> 2 <add name="SchoolContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ContosoUniversity1;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/> 3 </connectionStrings> 4 <appSettings> 5 <add key="webpages:Version" value="3.0.0.0" /> 6 <add key="webpages:Enabled" value="false" /> 7 <add key="ClientValidationEnabled" value="true" /> 8 <add key="UnobtrusiveJavaScriptEnabled" value="true" /> 9 </appSettings>
你添加的数据库连接字符串指定实体框架使用LocalDb作为数据库引擎,建立一个名为ContosoUniversity1.mdf的数据库(当前数据库还不存在,EF将自动创建它)。如果你想在你的App_data中存放数据库文件,您可以添加AttachDBFilename=|DataDirectory|\ContosoUniversity1.mdf到连接字符串。
添加学生控制器和视图
CTRL+F5 测试项目
查看数据库
记得关闭数据库连接!
约定
因为使用了约定,你用于编写建立一个完整数据库的代码量已经降低到了最少。这些约定已经在之前的教程中被你使用到,或许你没有意识到你正在使用它们,包括:
- 实体类型的复数形式被用作表名
- 实体属性名被用作列名
- 被命名为ID或实体名+ID的属性被用作主键。
- 当一个属性以<导航属性名><主键属性名>时被用作外键(例如,Student实体的主键是ID,则StudentID为导航属性的外键)。你也可以使用简单的<主键属性名>(例如,Enrollment实体的主键是EnrollmentID,你可以直接使用EnrollmentID)。
你已经看到,约定可以被覆盖。例如指定表的名称不应当使用复数形式,你会看到以后如何明确标记属性作为外键属性。你将在后面的教程中了解更多有关约定及如何重写它们
总结
现在,您已经创建了一个使用实体框架和SQL Server Express LocalDB来存储和显示数据的简单Web应用程序,在后面的教程中,您将学习如何执行基本的CRUD操作。