MVC5+EF6 入門完整教程四

上篇文章主要講了如何配置EF, 咱們回顧下主要過程:html

建立Data Model à 建立Database Context à建立databaseInitializerà配置entityFramework的context配置節。數據庫

對這個過程還有疑問的能夠去上篇再看一下。編程

本次咱們就主要講解 (1) EF基本的CRUD (2) 涉及到的經常使用HtmlHelper設計模式

文章提綱

概述 & 要點瀏覽器

理論基礎服務器

詳細步驟架構

總結app

概述 & 要點

下面是本文要點,正文部分會有詳細介紹。dom

  • EF數據模型的CRUD
  • 經常使用的HtmlHelper
  • Repository Pattern

理論基礎 -- EF 三種編程方式 (略)

總共有三種方式:函數

Database First,Model First和Code First,咱們採用的是code first.

這方面資料不少,我就不重複講述了, 須要瞭解這三者差別和應用場景的請自行查閱其餘資料。

理論基礎 -- EF CRUD

針對以前建立的SysUser, SysRole, SysUserRole舉一些典型例子,基本的CRUD你們在使用時模仿這些例子就能夠了。

咱們要用的數據庫示例數據分別以下:    

SysUser

SysRole

SysUserRole

EF數據查詢

先講使用頻率最高的查詢部分。     

EF數據查詢用LINQ實現(LINQ to Entities),一般有表達式和函數式兩種方式。建議用函數式方式,比較簡單。

假設咱們已經定義好了context

private AccountContext db = new AccountContext();

  1. [基本查詢] 查詢全部的SysUser

    var users = from u in db.SysUsers

    select u; //表達式方式

users = db.SysUsers; //函數式方式

  1. [條件查詢] 加入查詢條件

    users = from u in db.SysUsers

    where u.UserName == "Tom"

    select u; //表達式方式

    users = db.SysUsers.Where(u => u.UserName == "Tom"); //函數式方式

    NOTE 注意這邊等號是C#寫法 : " == "

  1. [排序和分頁查詢]

    users = (from u in db.SysUsers

    orderby u.UserName

    select u).Skip(0).Take(5); //表達式方式

    users = db.SysUsers.OrderBy(u => u.UserName).Skip(0).Take(5); //函數式方式

    NOTE 只有排序了才能分頁

  1. [聚合查詢]

    //查user總數

    var num = db.SysUsers.Count();

    //查最小ID

 minId = db.SysUsers.Min(u => u.ID);

    NOTE 聚合查詢只能經過函數式查詢

  1. [鏈接查詢]

    var users = from ur in db. SysUserRoles

    join u in db. SysUsers

    on ur.SysUserID equals u.ID

 ur;

NOTE

你們注意,鏈接查詢返回的結果仍是一個類型爲SysUserRoles的集合,只是用

了內鏈接進行了的篩選。

那麼問題來了,若是我須要選擇一個集合,裏面包括多張表,如SysUser裏面的UserName和SysRole裏面的RoleName怎麼辦?

這個是經過navigation property來實現的, 前面新建model的時候提到過,例如SysUser裏面的

public virtual ICollection<SysUserRole> SysUserRoles { get; set; }

但這種作法仍是不是太靈活,具體作法咱們在下面的詳細步驟裏面講。

EF數據更新

UPDATE步驟比較清晰,直接看下面代碼。

//數據更新,分三步:找到對象--> 更新對象數據--> 保存更改

public ActionResult EFUpdateDemo()

{

//1.找到對象

var sysUser = db.SysUsers.FirstOrDefault(u => u.UserName == "Tom");

//2.更新對象數據

if (sysUser != null)

{

sysUser.UserName = "Tom2";

}

//3.保存修改

db.SaveChanges();

return View();

}

EF數據添加/刪除

與UPDATE相似。

//數據添加和刪除

public ActionResult EFAddOrDeleteDemo()

{

//添加

//1.建立新的實體

var newSysUser = new SysUser()

{

UserName = "Scott",

Password = "tiger",

Email = "Scott@sohu.com"

};

//2.增長

db.SysUsers.Add(newSysUser);

//3.保存修改

db.SaveChanges();

 

//刪除

//1.找到須要刪除的對象

var delSysUser = db.SysUsers.FirstOrDefault(u => u.UserName == "Scott");

//2.刪除

if (delSysUser!=null)

{

db.SysUsers.Remove(delSysUser);

}

//3.保存修改

db.SaveChanges();

return View("EFQueryDemo");

}

詳細步驟

  • 查詢用戶及相應角色的功能
  • 修改用戶
  • 增長用戶和刪除用戶

查詢用戶及相應的角色

  1. 在Controller中修改Index方法,添加相關View, 顯示全部用戶
    1. 將model做爲參數傳過去

    2. Views à Account à Index.cshtml 頂部添增強類型聲明,

      @model IEnumerable<MVCDemo.Models.SysUser>

      body中添加個table用來顯示數據

      NOTE

      @Html.ActionLink("Details", "Details", new { id = item.ID })生成一個相同controller下的路由地址。

      顯示結果

       

  2. 增長一個Details方法,添加相關View, 顯示相應用戶及對應的角色
    1. 將特定的model傳過去

       

    2. Views à Account à Index.cshtml 頂部添增強類型聲明

      @model MVCDemo.Models.SysUser

      顯示數據,注意方框部分如何導航到另一張表的信息中。

      顯示結果

       

更新用戶,增長用戶,刪除用戶

這三個操做都相似,屬於更新的範疇,咱們放在一塊兒來說。

  1. 修改Views à Account à Index.cshtml

    開頭增長Create連接。

    table每條記錄後面增長Edit,Delete連接。

     

  2. 在Controller中增長相應的方法。

    新建用戶:

//新建用戶

public ActionResult Create()

{

return View();

}

[HttpPost]

public ActionResult Create(SysUser sysUser)

{

db.SysUsers.Add(sysUser);

db.SaveChanges();

return RedirectToAction("Index");

}

修改用戶:

//修改用戶

public ActionResult Edit(int id)

{

SysUser sysUser = db.SysUsers.Find(id);

return View(sysUser);

}

[HttpPost]

public ActionResult Edit(SysUser sysUser)

{

db.Entry(sysUser).State = EntityState.Modified;

db.SaveChanges();

return RedirectToAction("Index");

}

刪除用戶:

//刪除用戶

public ActionResult Delete(int id)

{

SysUser sysUser = db.SysUsers.Find(id);

return View(sysUser);

}

[HttpPost, ActionName("Delete")]

public ActionResult DeleteConfirmed(int id)

{

SysUser sysUser = db.SysUsers.Find(id);

db.SysUsers.Remove(sysUser);

db.SaveChanges();

return RedirectToAction("Index");

}

NOTE

涉及到數據更新的地方都有兩個同名的方法重載,一個用來顯示[HttpGet],一個用來數據更新[HttpPost]

  1. 在右鍵方法名,生成相應的View

    每一個View的頂部須要添加一個聲明

    @model MVCDemo.Models.SysUser

    各個view的body中具體代碼:

    Create.cshtml

    <body>

<div>

<h2>Create</h2>

@using (Html.BeginForm())

{

<div>

@Html.LabelFor(model => model.UserName)

@Html.EditorFor(model => model.UserName)

</div>

<div>

@Html.LabelFor(model => model.Email)

@Html.EditorFor(model => model.Email)

</div>

<div>

@Html.LabelFor(model => model.Password)

@Html.PasswordFor(model => model.Password)

</div>

<div>

<input type="submit" value="Create" />

</div>

}

<div>@Html.ActionLink("Back to List","Index")</div>

</div>

</body>

Edit.cshtml

<body>

<div>

<h2>Edit</h2>

@using (Html.BeginForm())

{

@Html.HiddenFor(model => model.ID)

<div>

@Html.LabelFor(model => model.UserName)

@Html.EditorFor(model => model.UserName)

</div>

<div>

@Html.LabelFor(model => model.Email)

@Html.EditorFor(model => model.Email)

</div>

<div>

@Html.LabelFor(model => model.Password)

@Html.PasswordFor(model => model.Password)

</div>

<div>

<input type="submit" value="Save" />

</div>

}

<div>@Html.ActionLink("Back to List","Index")</div>

</div>

>

Delete.cshtml

<body>

<div>

<h2>Delete</h2>

<h3>Are you sure you want to delete this? </h3>

<h4>User</h4>

<dl>

<dt>@Html.DisplayNameFor(model => model.UserName)</dt>

<dd>@Html.DisplayFor(model => model.UserName)</dd>

 

<dt>@Html.DisplayNameFor(model => model.Email)</dt>

<dd>@Html.DisplayFor(model => model.Email)</dd>

</dl>

 

@using (Html.BeginForm())

{

<div>

<input type="submit" value="Delete" />

</div>

}

<div>

@Html.ActionLink("Back to List", "Index")

</div>

</div>

>

NOTE

針對上面這些代碼,咱們提一下其中用到的HtmlHelper, 主要有這麼幾個:

DisplayNameFor (model=>model.xxx)à 生成純文本,顯示xxx列名

DisplayFor (model=>model.xxx)à 生成純文本,顯示xxx列的內容

LableFor à 生成一個Lable標籤

EditorFor à 生成一個text類型的input

PasswordFor à 相似於EditorFor, 隱藏文本內容

ActionLink à 生成一個<a>標籤

BeginForm à 生成一個表單

NOTE

HtmlHelper是能夠經過View的Html屬性調用的方法(@Html.xxx), 能夠類比成原來WebForm的服務器端控件, 後續文章會將分紅幾類, 歸類進行介紹,這裏先簡單提一下作個鋪墊。這塊最好的學習方法是用瀏覽器打開相應的頁面,View page source,查看生成的相應HTML代碼。

Repository Pattern

最好再補充下Repository Pattern,爲下篇文章重構代碼作個鋪墊。

Repository Pattern是一種設計模式,這個概念你們確定常常聽到。

"企業架構模式" 上的定義:

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

具體的作法:

先定義Interface, 經過定義接口肯定數據訪問類的功能需求, 接着實現該接口。

以對SysUser這張表的操做爲例。

先建一個文件夾 Repositories, 在文件夾中新建一個接口IsysUserRepository

咱們預先定義幾個功能。

namespace MVCDemo.Repositories

{

public interface ISysUserRepository

{

//查詢全部用戶

IQueryable<SysUser> SelectAll();

//經過用戶名查詢用戶

SysUser SelectByName(string userName);

//添加用戶

void Add(SysUser sysUser);

//刪除用戶

bool Delete(int id);

 

}

}

一樣文件夾下新建類,繼承接口,實現功能。

namespace MVCDemo.Repositories

{

public class SysUserRepository : ISysUserRepository

{

protected AccountContext db = new AccountContext();

//查詢全部用戶

public IQueryable<SysUser> SelectAll()

{

return db.SysUsers;

}

//經過用戶名查詢用戶

public SysUser SelectByName(string userName)

{

return db.SysUsers.FirstOrDefault(u => u.UserName == userName);

}

//添加用戶

public void Add(SysUser sysUser)

{

db.SysUsers.Add(sysUser);

db.SaveChanges();

}

//刪除用戶

public bool Delete(int id)

{

var delSysUser=db.SysUsers.FirstOrDefault(u => u.ID == id);

if (delSysUser != null)

{

db.SysUsers.Remove(delSysUser);

db.SaveChanges();

return true;

}

else

{

return false;

}

}

}

}

經過IsysUserRepository接口對象引用SysUserRepository類的實例來調用:

ISysUserRepository ur=new SysUserRepository();

var user=ur.xxx;

怎麼樣,平時聽到的Repository Pattern實現起來就這麼簡單。

樓主提示 設計模式都來源於編程實踐,只要掌握其中幾個重要原則,GOF總結的設計模式都能本身推導出來,就相似於幾何中的公理和定理的關係。你們工做中作個有心人,多思考,多總結。

 

總結

OK,到此爲止,咱們對經常使用的CRUD作了介紹。View, Controller之間都是經過傳遞Model來交互的。特別要提下下面這張圖,經過navigation property實現SysUser à SysUserRole à SysRole 多表間查詢。

固然,這種作法仍是有侷限性的,後續文章中咱們會介紹如何實現相似於以前SQL查詢多個表,將多個表的查詢結果,例如datatable直接傳到view中來顯示數據。

好了,今天就到這裏。

相關文章
相關標籤/搜索