MVC5+EF6 入門完整教程四


原文:https://www.cnblogs.com/miro/p/4072870.html

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

創建Data Model à 創建Database Context à創建databaseInitializerà配置entityFramework的context配置節。

對這個過程還有疑問的可以去上篇再看一下。

本次我們就主要講解 (1) EF基本的CRUD (2) 涉及到的常用HtmlHelper

文章提綱

概述 & 要點

理論基礎

詳細步驟

總結

概述 & 要點

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

  • 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();
//[基本查詢] 查詢所有的SysUser
    var users = from u in db.SysUsers
    select u; //表達式方式
users = db.SysUsers; //函數式方式
//[條件查詢] 加入查詢條件
    users = from u in db.SysUsers
    where u.UserName == "Tom"
    select u; //表達式方式
    users = db.SysUsers.Where(u => u.UserName == "Tom"); //函數式方式
    //NOTE 注意這邊等號是C#寫法 : " == "
//[排序和分頁查詢]
    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 只有排序了才能分頁
//[聚合查詢]
    //查user總數
    var num = db.SysUsers.Count();
    //查最小ID
    var minId = db.SysUsers.Min(u => u.ID);
    //NOTE 聚合查詢只能通過函數式查詢
//[連接查詢]
    var users = from ur in db. SysUserRoles
    join u in db. SysUsers
    on ur.SysUserID equals u.ID
  select 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>
</body>

 

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>
</body>

 

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中來顯示數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM