在前面的教程中,我们使用了一个简单的数据模型,包括三个数据实体。在这个教程汇中,我们将添加更多的实体和关系,按照特定的格式和验证规则等自定义数据模型。

Contoso大学校园管理系统的数据模型如下。

 一、修改学生实体

1.DataType Attribute

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; namespace ContosoUniversity.Models
{
public class Student
{
public int StudentID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; } [DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}

DataType.Date定义了日期显示不包括时间。DataType的枚举定义了很多类型,比如Date、Time、PhoneNumber、Currency、EmailAddress等。它并不包含验证规则。

DisplayFormat属性用来显式指定日期格式,ApplyFormatInEditMode设置指定将当前格式应用到,值显示在可编辑的文本框中。

2.StringLengthAttribute

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; namespace ContosoUniversity.Models
{
public class Student
{
public int StudentID { get; set; }
[StringLength()]
public string LastName { get; set; }
[StringLength(, ErrorMessage = "First name cannot be longer than 50 characters.")]
public string FirstMidName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}

StringLength规定字符串长度必须在某个值内,但是不会阻止用户提交空的字段值。复杂的验证规则可以使用正则表达式验证RegularExpression属性。

3.列属性

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace ContosoUniversity.Models
{
public class Student
{
public int StudentID { get; set; }
[StringLength()]
public string LastName { get; set; }
[StringLength(, ErrorMessage = "First name cannot be longer than 50 characters.")]
[Column("FirstName")]
public string FirstMidName { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}

FirstMidName属性对应到数据库中的列字段名为FirstName。

二、创建老师Instructor实体 

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace ContosoUniversity.Models
{
public class Instructor
{
public int InstructorID { get; set; } [Required]
[Display(Name = "Last Name")]
[StringLength()]
public string LastName { get; set; } [Required]
[Column("FirstName")]
[Display(Name = "First Name")]
[StringLength()]
public string FirstMidName { get; set; } [DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Hire Date")]
public DateTime HireDate { get; set; } public string FullName
{
get { return LastName + ", " + FirstMidName; }
} public virtual ICollection<Course> Courses { get; set; }
public virtual OfficeAssignment OfficeAssignment { get; set; }
}
}

你可以在一行上放入多个属性。

public class Instructor
{
public int InstructorID { get; set; } [Display(Name = "Last Name"),StringLength(, MinimumLength=)]
public string LastName { get; set; } [Column("FirstName"),Display(Name = "First Name"),StringLength(, MinimumLength=)]
public string FirstMidName { get; set; } [DataType(DataType.Date),Display(Name = "Hire Date"),DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime HireDate { get; set; } public string FullName
{
get { return LastName + ", " + FirstMidName; }
} public virtual ICollection<Course> Courses { get; set; }
public virtual OfficeAssignment OfficeAssignment { get; set; }
}

FullName是一个计算属性,它返回连接两个属性的值,只有get,在数据库中并不创建列字段。

三、创建办公地点OfficeAssignment实体

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace ContosoUniversity.Models
{
public class OfficeAssignment
{
[Key]
[ForeignKey("Instructor")]
public int InstructorID { get; set; }
[StringLength()]
[Display(Name = "Office Location")]
public string Location { get; set; } public virtual Instructor Instructor { get; set; }
}
}

InstructorID是主键也是教师实体的外键,因为InstructorID不能识别为主键,主键必须是类名ID或者ID,所以需要加[Key]。

四、修改课程Course实体

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace ContosoUniversity.Models
{
public class Course
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Display(Name = "Number")]
public int CourseID { get; set; } [StringLength(, MinimumLength = )]
public string Title { get; set; } [Range(, )]
public int Credits { get; set; } [Display(Name = "Department")]
public int DepartmentID { get; set; } public virtual Department Department { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
public virtual ICollection<Instructor> Instructors { get; set; }
}
}

五、创建系部Department实体

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace ContosoUniversity.Models
{
public class Department
{
public int DepartmentID { get; set; } [StringLength(, MinimumLength=)]
public string Name { get; set; } [DataType(DataType.Currency)]
[Column(TypeName = "money")]
public decimal Budget { get; set; } [DataType(DataType.Date)]
public DateTime StartDate { get; set; } [Display(Name = "Administrator")]
public int? InstructorID { get; set; } public virtual Instructor Administrator { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
}

Column属性改变了列字段的类型。
六、修改学生Student实体

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace ContosoUniversity.Models
{
public class Student
{
public int StudentID { get; set; } [StringLength(, MinimumLength = )]
public string LastName { get; set; } [StringLength(, MinimumLength = , ErrorMessage = "First name cannot be longer than 50 characters.")]
[Column("FirstName")]
public string FirstMidName { get; set; } [DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Enrollment Date")]
public DateTime EnrollmentDate { get; set; } public string FullName
{
get { return LastName + ", " + FirstMidName; }
} public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}

七、修改注册Enrollment实体

using System.ComponentModel.DataAnnotations;

namespace ContosoUniversity.Models
{
public enum Grade
{
A, B, C, D, F
} public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; } [DisplayFormat(NullDisplayText = "No grade")]
public Grade? Grade { get; set; } public virtual Course Course { get; set; }
public virtual Student Student { get; set; }
}
}

 八、使用Seed方法为数据库注入测试数据

namespace ContosoUniversity.Migrations
{
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
using ContosoUniversity.Models;
using ContosoUniversity.DAL; internal sealed class Configuration : DbMigrationsConfiguration<SchoolContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
} protected override void Seed(SchoolContext context)
{
var students = new List<Student>
{
new Student { FirstMidName = "Carson", LastName = "Alexander",
EnrollmentDate = DateTime.Parse("2010-09-01") },
new Student { FirstMidName = "Meredith", LastName = "Alonso",
EnrollmentDate = DateTime.Parse("2012-09-01") },
new Student { FirstMidName = "Arturo", LastName = "Anand",
EnrollmentDate = DateTime.Parse("2013-09-01") },
new Student { FirstMidName = "Gytis", LastName = "Barzdukas",
EnrollmentDate = DateTime.Parse("2012-09-01") },
new Student { FirstMidName = "Yan", LastName = "Li",
EnrollmentDate = DateTime.Parse("2012-09-01") },
new Student { FirstMidName = "Peggy", LastName = "Justice",
EnrollmentDate = DateTime.Parse("2011-09-01") },
new Student { FirstMidName = "Laura", LastName = "Norman",
EnrollmentDate = DateTime.Parse("2013-09-01") },
new Student { FirstMidName = "Nino", LastName = "Olivetto",
EnrollmentDate = DateTime.Parse("2005-09-01") }
}; students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, s));
context.SaveChanges(); var instructors = new List<Instructor>
{
new Instructor { FirstMidName = "Kim", LastName = "Abercrombie",
HireDate = DateTime.Parse("1995-03-11") },
new Instructor { FirstMidName = "Fadi", LastName = "Fakhouri",
HireDate = DateTime.Parse("2002-07-06") },
new Instructor { FirstMidName = "Roger", LastName = "Harui",
HireDate = DateTime.Parse("1998-07-01") },
new Instructor { FirstMidName = "Candace", LastName = "Kapoor",
HireDate = DateTime.Parse("2001-01-15") },
new Instructor { FirstMidName = "Roger", LastName = "Zheng",
HireDate = DateTime.Parse("2004-02-12") }
};
instructors.ForEach(s => context.Instructors.AddOrUpdate(p => p.LastName, s));
context.SaveChanges(); var departments = new List<Department>
{
new Department { Name = "English", Budget = ,
StartDate = DateTime.Parse("2007-09-01"),
InstructorID = instructors.Single( i => i.LastName == "Abercrombie").InstructorID },
new Department { Name = "Mathematics", Budget = ,
StartDate = DateTime.Parse("2007-09-01"),
InstructorID = instructors.Single( i => i.LastName == "Fakhouri").InstructorID },
new Department { Name = "Engineering", Budget = ,
StartDate = DateTime.Parse("2007-09-01"),
InstructorID = instructors.Single( i => i.LastName == "Harui").InstructorID },
new Department { Name = "Economics", Budget = ,
StartDate = DateTime.Parse("2007-09-01"),
InstructorID = instructors.Single( i => i.LastName == "Kapoor").InstructorID }
};
departments.ForEach(s => context.Departments.AddOrUpdate(p => p.Name, s));
context.SaveChanges(); var courses = new List<Course>
{
new Course {CourseID = , Title = "Chemistry", Credits = ,
DepartmentID = departments.Single( s => s.Name == "Engineering").DepartmentID,
Instructors = new List<Instructor>()
},
new Course {CourseID = , Title = "Microeconomics", Credits = ,
DepartmentID = departments.Single( s => s.Name == "Economics").DepartmentID,
Instructors = new List<Instructor>()
},
new Course {CourseID = , Title = "Macroeconomics", Credits = ,
DepartmentID = departments.Single( s => s.Name == "Economics").DepartmentID,
Instructors = new List<Instructor>()
},
new Course {CourseID = , Title = "Calculus", Credits = ,
DepartmentID = departments.Single( s => s.Name == "Mathematics").DepartmentID,
Instructors = new List<Instructor>()
},
new Course {CourseID = , Title = "Trigonometry", Credits = ,
DepartmentID = departments.Single( s => s.Name == "Mathematics").DepartmentID,
Instructors = new List<Instructor>()
},
new Course {CourseID = , Title = "Composition", Credits = ,
DepartmentID = departments.Single( s => s.Name == "English").DepartmentID,
Instructors = new List<Instructor>()
},
new Course {CourseID = , Title = "Literature", Credits = ,
DepartmentID = departments.Single( s => s.Name == "English").DepartmentID,
Instructors = new List<Instructor>()
},
};
courses.ForEach(s => context.Courses.AddOrUpdate(p => p.CourseID, s));
context.SaveChanges(); var officeAssignments = new List<OfficeAssignment>
{
new OfficeAssignment {
InstructorID = instructors.Single( i => i.LastName == "Fakhouri").InstructorID,
Location = "Smith 17" },
new OfficeAssignment {
InstructorID = instructors.Single( i => i.LastName == "Harui").InstructorID,
Location = "Gowan 27" },
new OfficeAssignment {
InstructorID = instructors.Single( i => i.LastName == "Kapoor").InstructorID,
Location = "Thompson 304" },
};
officeAssignments.ForEach(s => context.OfficeAssignments.AddOrUpdate(p => p.Location, s));
context.SaveChanges(); AddOrUpdateInstructor(context, "Chemistry", "Kapoor");
AddOrUpdateInstructor(context, "Chemistry", "Harui");
AddOrUpdateInstructor(context, "Microeconomics", "Zheng");
AddOrUpdateInstructor(context, "Macroeconomics", "Zheng"); AddOrUpdateInstructor(context, "Calculus", "Fakhouri");
AddOrUpdateInstructor(context, "Trigonometry", "Harui");
AddOrUpdateInstructor(context, "Composition", "Abercrombie");
AddOrUpdateInstructor(context, "Literature", "Abercrombie"); context.SaveChanges(); var enrollments = new List<Enrollment>
{
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alexander").StudentID,
CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID,
Grade = Grade.A
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alexander").StudentID,
CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID,
Grade = Grade.C
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alexander").StudentID,
CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alonso").StudentID,
CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alonso").StudentID,
CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Alonso").StudentID,
CourseID = courses.Single(c => c.Title == "Composition" ).CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Anand").StudentID,
CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Anand").StudentID,
CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Barzdukas").StudentID,
CourseID = courses.Single(c => c.Title == "Chemistry").CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Li").StudentID,
CourseID = courses.Single(c => c.Title == "Composition").CourseID,
Grade = Grade.B
},
new Enrollment {
StudentID = students.Single(s => s.LastName == "Justice").StudentID,
CourseID = courses.Single(c => c.Title == "Literature").CourseID,
Grade = Grade.B
}
}; foreach (Enrollment e in enrollments)
{
var enrollmentInDataBase = context.Enrollments.Where(
s =>
s.Student.StudentID == e.StudentID &&
s.Course.CourseID == e.CourseID).SingleOrDefault();
if (enrollmentInDataBase == null)
{
context.Enrollments.Add(e);
}
}
context.SaveChanges();
} void AddOrUpdateInstructor(SchoolContext context, string courseTitle, string instructorName)
{
var crs = context.Courses.SingleOrDefault(c => c.Title == courseTitle);
var inst = crs.Instructors.SingleOrDefault(i => i.LastName == instructorName);
if (inst == null)
crs.Instructors.Add(context.Instructors.Single(i => i.LastName == instructorName));
}
}
}

 九、模型迁移

在PMC, 输入add-migration命令:

PM> add-Migration Chap4

此时更新数据库,可能会得到如下错误:

The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_dbo.Course_dbo.Department_DepartmentID". The conflict occurred in database "ContosoUniversity", table "dbo.Department", column 'DepartmentID'.

编辑<timestamp>_Chap4.cs模型迁移文件, 修改代码如下:

CreateTable(
"dbo.CourseInstructor",
c => new
{
CourseID = c.Int(nullable: false),
InstructorID = c.Int(nullable: false),
})
.PrimaryKey(t => new { t.CourseID, t.InstructorID })
.ForeignKey("dbo.Course", t => t.CourseID, cascadeDelete: true)
.ForeignKey("dbo.Instructor", t => t.InstructorID, cascadeDelete: true)
.Index(t => t.CourseID)
.Index(t => t.InstructorID); // Create a department for course to point to.
Sql("INSERT INTO dbo.Department (Name, Budget, StartDate) VALUES ('Temp', 0.00, GETDATE())");
// default value for FK points to department created above.
AddColumn("dbo.Course", "DepartmentID", c => c.Int(nullable: false, defaultValue: ));
//AddColumn("dbo.Course", "DepartmentID", c => c.Int(nullable: false)); AlterColumn("dbo.Course", "Title", c => c.String(maxLength: ));
AddForeignKey("dbo.Course", "DepartmentID", "dbo.Department", "DepartmentID", cascadeDelete: true);
CreateIndex("dbo.Course", "DepartmentID");
} public override void Down()
{

(确保你已经删除了多余的AddColumn,如果迁移不成功,可将数据库删除后再试。)

演练5-3:Contoso大学校园管理系统3的更多相关文章

  1. 演练5-5:Contoso大学校园管理系统5

    Contoso University示例网站演示如何使用Entity Framework 5创建ASP.NET MVC 4应用程序. Entity Framework有三种处理数据的方式:  Data ...

  2. 演练5-6:Contoso大学校园管理系统6

    在上一次的教程中,我们处理了关联数据问题.这个教程演示如何处理并发问题.你将使用Department实体创建一个页面,这个页面在支持编辑和删除的同时,还可以处理并发错误.下面的截图演示了Index页面 ...

  3. 演练5-4:Contoso大学校园管理系统4

    在之前的教程中,我们已经完成了学校的数据模型.现在我们将读取和显示相关数据,请理解EF加载导航属性的方式. 一.Lazy.Eager.Explicit数据加载 使用EF为实体中的导航属性加载相关数据, ...

  4. 演练5-7:Contoso大学校园管理系统(实现继承)

    ***操作视频下载:1     *** 在上一次教程中,你已经能够处理并发异常.这个教程将会展示如何在数据模型中实现继承. 在面向对象的程序设计中,你可以通过继承来清除冗余的代码.在这个教程中,你将要 ...

  5. 演练5-8:Contoso大学校园管理系统(实现存储池和工作单元模式)

    在上一次的教程中,你已经使用继承来消除在 Student 和 Instructor 实体之间的重复代码.在这个教程中,你将要看到使用存储池和工作单元模式进行增.删.改.查的一些方法.像前面的教程一样, ...

  6. 演练5-1:Contoso大学校园管理1

    **演练目的:掌握复杂模型的应用程序开发. Contoso大学校园管理系统功能包括学生.课程.教师的管理. 一.创建MVC Web应用程序 显示效果如下图,操作步骤略. 二.创建数据模型 1.创建学生 ...

  7. 演练5-2:Contoso大学校园管理2

    一.添加列标题排序功能 我们将增加Student/Index页面的功能,为列标题添加超链接,用户可以点击列标题对那一列进行排序. 1.修改Index方法 public ActionResult Ind ...

  8. Contoso 大学 - 使用 EF Code First 创建 MVC 应用,实例演练

    Contoso 大学 Web 示例应用演示了如何使用 EF 技术创建 ASP.NET MVC 应用.示例中的 Contoso 大学是虚构的.应用包括了类似学生注册.课程创建以及教师分配等功能. 这个系 ...

  9. Contoso 大学 - 7 – 处理并发

    原文 Contoso 大学 - 7 – 处理并发 By Tom Dykstra, Tom Dykstra is a Senior Programming Writer on Microsoft's W ...

随机推荐

  1. OFbiz--HelloWorld

    上篇博客<OFbiz--简单介绍>我们介绍了OFbiz是什么,以下我们就開始用OFbiz开发我们的第一个程序--HelloWorld. 过程例如以下: 首先在hot-deploy下新建文件 ...

  2. .net Windows服务程序和安装程序制作图解

    最近项目中用到window服务程序,以前没接触过,比较陌生,花了两天的时间学习了下,写了个简单的服务,但在制作安装程序的时候,参照网上很多资料,却都制作不成功,可能是开发环境或项目配置的不同,这里把自 ...

  3. ASP.NET 操作配置文件

    1.配置文件的各种操作 http://www.cnblogs.com/shimeng3344518/archive/2007/04/23/723999.html 2. http://www.jb51. ...

  4. 经典排序算法及python实现

    今天我们来谈谈几种经典排序算法,然后用python来实现,最后通过数据来比较几个算法时间 选择排序 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是每一次从待排序的数据 ...

  5. 裸机离奇事件:Freescale usb 有关fault

    裸机离奇事件:Freescale usbucosiiFreescale\KSDK_1.2.0\examples\twrk65f180m\demo_apps\usb\host\cdc\cdc_seria ...

  6. python安装zlib一直无效

    一直按网上的方法: 1.先安装 apt-get install zlib1g-dev 2.重新安装python(3.3):即是./configure 再make再make install 始终没有解决 ...

  7. CentOS 6.5 PYPI本地源制作

    转载:blog.csdn.net/tantexian   一.安装pip2pi工具: pip install pip2pi 或 git clone https://github.com/wolever ...

  8. Objective-C 程序设计第四版

    1,@class  XYPoint; 写在.h文件里,告诉编译器有这类,然后用的时候,其实是在.m文件引入的. 例如.#import “XYPoint.h”  然后在.m文件里就能用XYPoint.h ...

  9. Publisher/Subscriber 订阅-发布模式

    Publisher/Subscriber 订阅-发布模式 本博后续将陆续整理这些年做的一些预研demo,及一些前沿技术的研究,与大家共研技术,共同进步. 关于发布订阅有很多种实现方式,下面主要介绍WC ...

  10. CSDN书籍下载

    http://download.csdn.net/user/vanridin/uploads/38 (2016英文书下载) http://download.csdn.net/user/ramissue ...