文章一 MVC核心概念簡介,一個基本MVC項目結構html
文章二 經過開發一個最基本的登陸界面,介紹瞭如何從Controller中獲取表單數據數據庫
文章三 EF的整個開發過程服務器
文章四 EF基本的CRUD和經常使用的HtmlHelperapp
文章五 使用佈局頁(模板頁)改造UI函數
文章六 分部視圖(Partial View)佈局
文章七 排序過濾分頁post
文章八 不丟失數據進行數據庫結構升級測試
以上若是有不清楚的能夠再回去看一下。ui
基於前面的文章,本次咱們更近一步,進行更加深刻的講解, 首先介紹下Attribute配置Data Model.this
使用Attribute配置Data Model, 能夠指定formatting, validation, database mapping rules
約定:下圖中三種狀況通常資料都翻譯成"屬性",爲了區分,咱們用下圖中的表述方式。
接下來,咱們先對經常使用的attribute進行舉例說明。
首先打開ModelsàSysUser.cs
添加 public DateTime CreateDate { get; set; }
增長完以後及時使用Code First Migrations 方式更新數據庫。(否則運行時會報contex和database不一致的錯誤)
注意把Migrations\ Configuration.cs中Seed方法中內容註釋掉,由於
運行 add-migration AddCreateDateToSysUser,update-database便可更新
Code First Migrations 方式更新數據庫詳細作法參加上篇文章。
接着修改Views\Account\Index.cshtml,把建立日期顯示出來,以下方框處。
你們注意到,默認狀況下會顯示出時間,咱們只須要顯示到日就能夠了。
DataType 屬性用來指定更加具體的數據類型,DataType枚舉值提供了一些常見的類型,好比Date,Time,EmailAddress等。
可是DataType不能指定數據類型的顯示格式,例如日期要什麼格式顯示。
這個時候就須要配合使用DisplayFormate屬性來指定格式。
[DisplayFormat(DataFormatString="{0:yyyy-MM-dd}",ApplyFormatInEditMode=true)]
StringLength屬性設置了數據庫中存儲字段的最大長度,爲程序提供客戶端和服務器端的驗證。一樣用這個屬性也能夠指定最小長度,不過不影響數據庫的結構。
add-migration MaxLengthOnNames
update-database
Views\Account\Create.cshtml增長一個Helper:ValidationMessageFor用來顯示驗證信息
Controllers\AccountController.cs增長一個判斷條件ModelState.IsValid,否則會出錯。
有時會有這麼一種狀況,咱們Model中的字段和數據庫中表的字段要用不一樣的命名。例如咱們Model中命名爲UserName,數據庫表中命名爲LoginName.
打開數據庫能夠看到UserName已經變成LoginName了。
下面再列出其餘經常使用的attribute, 就不舉展開講了,很容易能夠看懂,你們能夠本身嘗試。
[StringLength(10,MinimumLength=1,ErrorMessage="名字在1和10個字之間")]
[Column("FirstName"),Display(Name = "First Name"),StringLength(50, MinimumLength=1)]
2.對某一些類型來講不須要使用Required, 例如DateTime, int,double,float,由於這些值類型不能被賦予空值,所以他們天生就具備Required的特性。
[Column(TypeName="money")]
public decimal Budget { get; set; }
指定Column的TypeName能夠改變SQL data type,這個例子中就是知道使用SQL Server的money類型。
Column mapping通常來講不須要,由於EF一般會基於你爲property定義的CLR類型選擇合適的SQL Server data type.
The CLR decimal type maps to a SQL Server decimal type.
詳細對應表:https://msdn.microsoft.com/en-us/library/bb896344.aspx
前面文章中咱們介紹過顯示關聯表數據的方法。
第四篇文章介紹過經過navigation 屬性顯示關聯表數據。
本篇文章就係統的講解下多表關聯數據顯示的問題。
有三種方式EF能夠加載關聯數據到一個實體的navigation屬性中,下面我就直接用MSDN上的截圖來講明。
第一次讀取entity的時候不會加載。
當須要讀取navigation property的時候,相關的數據將會被自動讀取。
這種狀況會致使屢次查詢數據庫。
當讀取entity的時候,相關數據會被一塊兒讀取。
通常來講這種方式會產生一個join query來獲取全部須要的數據。
經過Include方法來指定eager loading.
和lazy loading相似,除了須要在代碼中明確指定須要獲取的關聯數據。
在讀取navigation property時explicit loading 不會自動發生,你須要手動加載相關數據。
經過獲取object state manager entry for entity,調用Collection.Load method for collections或者Reference.Load method for properties that hold a single entity.
通常來講,只有在關閉lazying loading的時候纔會使用explicit loading
lazy loading 和 explicit loading都不當即獲取property values,它們也被稱做deferred loading.
Disable lazy loading before serialization
disable lazy loading的兩種方式:
1.對特定的navigation properties來講,省略property的virtual關鍵字就能夠了
2.對全部navigation properties來講, 在context類中,構造函數中設置LazyingLoadingEnabled 爲false便可。
this.Configuration.LazyLoadingEnabled = false;
使用 code first migrations的方式更新下數據庫。能夠看到新的表結構已經生成了。
先看下原來的Views\Account\Index.cshtml
咱們原來是顯示SysUser主表內容,當點擊Details時經過navigation property實現SysUseràSysUserRoleàSysRole多表間查詢。
如今咱們增長一列Department, 讓這個表格能直接顯示SysUser主表及相應的Department內容。
咱們使用Eager Loading的方式將Department的內容也加載進去,打開Controllers\AccountController.cs, 在index修改一處地方:
運行,能夠看到Department中的內容已經被咱們加載進來了。
多對多關係能夠拆解成一對多的關係,例如用戶和角色(* to *)可拆解成:
爲了演示這個場景,咱們新建一個ViewModel,將須要顯示的表都放進去。
由於前面的文章已經將基本的用法都講過了,我這裏就直接貼出代碼以及最終的展現結果,若是有不理解的部分再給我留言。
Controllers\UserRoleController.cs:
using System.Collections.Generic;
public class UserRoleController : Controller
private AccountContext db = new AccountContext();
public ActionResult Index(int? id)
var viewModel = new UserRoleIndexData();
viewModel.SysUsers = db.SysUsers
.Include(u => u.SysUserRoles.Select(ur => ur.SysRole))
viewModel.SysUserRoles = viewModel.SysUsers.Where(u => u.ID == id.Value).Single().SysUserRoles;
viewModel.SysRoles = (viewModel.SysUserRoles.Where(
ur => ur.SysUserID == id.Value)).Select(ur=>ur.SysRole);
@model MVCDemo.ViewModels.UserRoleIndexData
Layout = "~/Views/Shared/_LayoutAdmin.cshtml";
@Html.ActionLink("Create New", "Create")
<table class="table table-striped">
@foreach (var item in Model.SysUsers)
@Html.DisplayFor(modelItem => item.UserName)
@Html.DisplayFor(modelItem => item.Email)
@Html.DisplayFor(modelItem => item.CreateDate)
@if (item.SysDepartment != null)
@item.SysDepartment.DepartmentName
foreach (var userRole in item.SysUserRoles)
@userRole.SysRole.RoleName <br />
@Html.ActionLink("Select", "Index", new { id = item.ID })
<table class="table table-striped">
@foreach (var item in Model.SysRoles)
[DisplayFormat(DataFormatString="{0:yyyy-MM-dd}",ApplyFormatInEditMode=true)]
[DisplayFormat(NullDisplayText = "No grade")]
[StringLength(10,MinimumLength=1,ErrorMessage="名字在1和10個字之間")]
好了,到目前爲止,使用MVC+EF開發的基本知識差很少都齊全了。
在下一課,也就是咱們第一階段的最後一課:MVC5+EF6入門完整教程十,咱們將再講解下數據更新的部分,以及如何使用原生SQL,如何調用存儲過程等。