MVC3+EF4.1学习系列(一)-------建立EF4.1 code first的第一个实例

基于EF4.1 code first 简单的CRUD  园子中已经有不少了 ~~ 真不想再写这个了 但是为了作一个完整的小demo 从开始 到后面的一些简单重构 仍是决定认真把这个写出来html

争取写些别人没写到的东西~~ 好了 开始~~数据库

此次要作的是个学校管理的demo(通俗些)mvc

 先建一个MVC3的应用程序  由于咱们是code first 因此 开始建立实体类ide

一.建立Model测试

学生和学生成绩登记表是一对多的关系  一个学生能够有屡次登记 (由于有多个课程)  一个课程也能够有多个登记   能够看出 其实就是 学生和课程 存在一个多对多的关系ui

为何这么创建模型呢?这节主要不是讨论关系 关系这个会放到  第三节来讨论~~spa

如今开始建立学生的实体类code

复制代码

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
   
public class Student
   {
       
public int StudentID { get; set; }
       
public string LastName { get; set; }
       
public string FirstMidName { get; set; }
       
public DateTime EnrollmentDate { get; set; }
       
public virtual ICollection<Enrollment> Enrollments { get; set; }
   }
}

复制代码

在这里面 这个StudentID将被默认的设为主键  EF将会默认的给名字为ID的或者带ID的设置为主键orm

Enrollments是一个导航属性  将作为外键    导航属性定义为virtual 以便于实现延迟加载 htm

  接下来 建立登记录入表(关系表)的实体类 

复制代码

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
   
public class Enrollment
   {
       
public int EnrollmentID { get; set; }
       
public int CourseID { get; set; }
       
public int StudentID { get; set; }
       
public decimal? Grade { get; set; }
       
public virtual Course Course { get; set; }
       
public virtual Student Student { get; set; }
   }
}

复制代码

这里面 咱们的成绩是可空类型     学生实体有多个 Enrollment 而Enrollment有一个学生实体的导航属性 这里面 咱们既有学生ID 又有学生实体属性 咱们会担忧 会不会生成两个呢StudentID?不用担忧 EF很聪明 在关系表里 只有一个studentID

接下来就是建立课程实体了

复制代码

using System;
using System.Collections.Generic;

namespace ContosoUniversity.Models
{
   
public class Course
   {
       
public int CourseID { get; set; }
       
public string Title { get; set; }
       
public int Credits { get; set; }
       
public virtual ICollection<Enrollment> Enrollments { get; set; }
   }
}

复制代码

OK了 实体建立好了 接下来 咱们要建立一个 数据库上下文

二.Creating the Database Context

这个类主要是把上面建立的实体类包含再里面  指定哪些实体类包含在咱们的数据模型中 还有 这个类能够指定咱们的映射关系 还能够指定一些生成的约束关系总之 颇有用的

这里面 咱们先建立一个DAL的文件夹 而后在下面新建一个类 叫作SchoolContext  而且继承DbContext

复制代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.Entity;
using ContosoUniversity.Models;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.Entity.Infrastructure;



namespace ContosoUniversity.DAL
{
   
public class SchoolContext:DbContext
   {
       
private readonly static string CONNECTION_STRING = "name=WlfSys_EFCF_ConnString";


       
public DbSet<Student> Students { get; set; }
       
public DbSet<Enrollment> Enrollments { get; set; }
       
public DbSet<Course> Courses { get; set; }

       
public SchoolContext()
           :
base(CONNECTION_STRING)//不写这个  默认的就是SchoolContext
       {

       }

       
protected override void OnModelCreating(DbModelBuilder modelBuilder)
       {
           modelBuilder.Conventions.Remove
<PluralizingTableNameConvention>();//移除复数表名的契约

          modelBuilder.Conventions.Remove
<IncludeMetadataConvention>();//防止黑幕交易 要否则每次都要访问 EdmMetadata这个表




           
/*
           
            能够删除的公约有:
Namespace:System.Data.Entity.ModelConfiguration.Conventions.Edm
• AssociationInverseDiscoveryConvention
寻找导航上互相引用的类的属性,并将它们配置为逆属性的相同的关系。
• ComplexTypeDiscoveryConvention
寻找有没有主键的类型,并将它们配置为复杂类型。
• DeclaredPropertyOrderingConvention
确保每一个实体的主要关键属性优先于其余属性。
• ForeignKeyAssociationMultiplicityConvention
配置是必需的仍是可选的关系基于为空性外键属性,若是包含在类定义中。
• IdKeyDiscoveryConvention
查找名为 Id 或 <TypeName> Id 的属性,并将他们配置做为主键。
• NavigationPropertyNameForeignKeyDiscoveryConvention
使用外键关系,使用 <NavigationProperty> <PrimaryKeyProperty> 模式做为属性的外观。
• OneToManyCascadeDeleteConvention
交换机上层叠删除,所需的关系。
• OneToOneConstraintIntroductionConvention
将配置为一个: 一个关系的外键的主键。
• PluralizingEntitySetNameConvention
配置为多元化的类型名称的实体数据模型中的实体集的名称。
• PrimaryKeyNameForeignKeyDiscoveryConvention
使用外键关系,使用 <PrimaryKeyProperty> 模式做为属性的外观。
• PropertyMaxLengthConvention
配置全部的字符串和字节 [] 属性,默认状况下具备最大长度。
• StoreGeneratedIdentityKeyConvention
配置默认状况下将标识全部整数的主键。
• TypeNameForeignKeyDiscoveryConvention
使用外键关系,使用 <PrincipalTypeName> <PrimaryKeyProperty> 模式做为属性的外观。

           
           
*/

       }

   }
}

复制代码

详细的解释下这里

 private readonly static string CONNECTION_STRING = "name=WlfSys_EFCF_ConnString";

 public SchoolContext()
           :
base(CONNECTION_STRING)//不写这个  默认的就是SchoolContext
       {

       }

上面这里是配置链接字符串  默认的就是SchoolContext 即你这个context的名字

复制代码

protected override void OnModelCreating(DbModelBuilder modelBuilder)
       {

  modelBuilder.Conventions.Remove
<PluralizingTableNameConvention>();//移除复数表名的契约

          modelBuilder.Conventions.Remove
<IncludeMetadataConvention>();//防止黑幕交易 要否则每次都要访问 EdmMetadata这个表

     }

复制代码

再重写的这个方法里 咱们能够移除一些契约  还能够配置数据库映射关系  经常使用的移除信息 都写在里面了

三.设置链接字符串

 <connectionStrings>
   
<add name="WlfSys_EFCF_ConnString"
       providerName
="System.Data.SqlClient" connectionString="Data Source=.;Initial Catalog=WLFSchool;Integrated Security=True;Pooling=False" />
 
</connectionStrings>

咱们的这个名字 和上面设置的一直~~(那个英文博客里用的是 SQL Server Compact database 但为了让项目贴近实际 我这里用SQL2005)

四.数据库数据初始化

在DAL下 新建一个类 SchoolInitializer  继承自 DropCreateDatabaseIfModelChanges<SchoolContext>  这个类主要实现 数据库数据初始化 方便测试~~

复制代码

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 : 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 { Title = "Chemistry",      Credits = 3, },
               
new Course { Title = "Microeconomics", Credits = 3, },
               
new Course { Title = "Macroeconomics", Credits = 3, },
               
new Course { Title = "Calculus",       Credits = 4, },
               
new Course { Title = "Trigonometry",   Credits = 4, },
               
new Course { Title = "Composition",    Credits = 3, },
               
new Course { Title = "Literature",     Credits = 4, }
           };
           courses.ForEach(s
=> context.Courses.Add(s));
           context.SaveChanges();

           var enrollments
= new List<Enrollment>
           {
               
new Enrollment { StudentID = 1, CourseID = 1, Grade = 1 },
               
new Enrollment { StudentID = 1, CourseID = 2, Grade = 3 },
               
new Enrollment { StudentID = 1, CourseID = 3, Grade = 1 },
               
new Enrollment { StudentID = 2, CourseID = 4, Grade = 2 },
               
new Enrollment { StudentID = 2, CourseID = 5, Grade = 4 },
               
new Enrollment { StudentID = 2, CourseID = 6, Grade = 4 },
               
new Enrollment { StudentID = 3, CourseID = 1            },
               
new Enrollment { StudentID = 4, CourseID = 1,           },
               
new Enrollment { StudentID = 4, CourseID = 2, Grade = 4 },
               
new Enrollment { StudentID = 5, CourseID = 3, Grade = 3 },
               
new Enrollment { StudentID = 6, CourseID = 4            },
               
new Enrollment { StudentID = 7, CourseID = 5, Grade = 2 },
           };
           enrollments.ForEach(s
=> context.Enrollments.Add(s));
           context.SaveChanges();

       }
   }
}

复制代码

这样尚未完 还要再 Global.asax 下的Application_Start()加上以下代码

 Database.SetInitializer<SchoolContext>(new SchoolInitializer());

五.建立控制器

 建立好后添加

    private SchoolContext db = new SchoolContext();

再在Index方法下添加获得全部学生的方法

public ViewResult Index()
{
   
return View(db.Students.ToList());
}

六.添加视图(小谈MVC的 DISPLAY)

复制代码

@model IEnumerable<ContosoUniversity.Models.Student>

@{
   ViewBag.Title = "Students";
}

<h2>Students</h2>

<p>
   @Html.ActionLink("Create New", "Create")
</p>
<table>
   
<tr>
       
<th></th>
       
<th>Last Name</th>
       
<th>First Name</th>
       
<th>Enrollment Date</th>
   
</tr>

@foreach (var item in Model) {
   
<tr>
       
<td>
           @Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) |
           @Html.ActionLink("Details", "Details", new { id=item.StudentID }) |
           @Html.ActionLink("Delete", "Delete", new { id=item.StudentID })
       
</td>
       
<td>
           @Html.DisplayFor(modelItem => item.LastName)
       
</td>
       
<td>
           @Html.DisplayFor(modelItem => item.FirstMidName)
       
</td>
       
<td>
           @Html.DisplayFor(modelItem => item.EnrollmentDate)
       
</td>
   
</tr>
}

</table>

复制代码

好了 视图添加完了 这里面 咱们用了 Html.DisplayFor  刚看到这个时 老是不明白这个到底显示什么 还有实体类上 老是加上display(name="")这样的特性 可是又和这个不要紧 让我很郁闷

查了MSDN和相关资料 终于明白  Html.DisplayFor 能够算是显示模版 显示实体类的特性[DataType(DataType.Password)] 这样显示的就是密码框   而 display(name="")这样的特性  则是让 Html.LabelFor()去显示的  display的具体的 能够看下这个文章 介绍的不错display模版详细介绍

七.运行环境 查看结果

你们必定很关心数据库的生成什么样子滴~~

EdmMetadata 数据库记录个版本对照 能够不要 在契约里有删除~~用站长dudu的话 防止黑幕交易

八.总结

很简单的建立一个EF4.1 代码优先的小例子 没什么难度~~ 但仍是认真的写了下来 好累哦

相关文章
相关标签/搜索