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 代碼優先的小例子 沒什麼難度~~ 但仍是認真的寫了下來 好累哦

相關文章
相關標籤/搜索