上篇文章主要讲了如何配置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();

  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中来显示数据。

好了,今天就到这里。

MVC5+EF6 入门完整教程四的更多相关文章

  1. MVC5+EF6 入门完整教程九

    前一阵子临时有事,这篇文章发布间隔比较长,我们先回顾下之前的内容,每篇文章用一句话总结重点. 文章一 MVC核心概念简介,一个基本MVC项目结构 文章二 通过开发一个最基本的登录界面,介绍了如何从Co ...

  2. MVC5+EF6 入门完整教程13 -- 动态生成多级菜单

    稍微有一定复杂性的系统,多级菜单都是一个必备组件. 本篇专题讲述如何生成动态多级菜单的通用做法. 我们不用任何第三方的组件,完全自己构建灵活通用的多级菜单. 需要达成的效果:容易复用,可以根据mode ...

  3. MVC5 + EF6 入门完整教程二

    从前端的UI开始 MVC分离的比较好,开发顺序没有特别要求,先开发哪一部分都可以,这次我们主要讲解前端UI的部分. ASP.NET MVC抛弃了WebForm的一些特有的习惯,例如服务器端控件,Vie ...

  4. MVC5+EF6 入门完整教程

    MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用 MVC5+EF6 入门完整教程10:多对多关联表更新&使用原生SQL@20150521 MVC5+EF6 入门完整教程9:多表 ...

  5. MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用

    摘要: 第一阶段1~10篇已经覆盖了MVC开发必要的基本知识. 第二阶段11-20篇将会侧重于专题的讲解,一篇文章解决一个实际问题. 根据园友的反馈, 本篇文章将会先对呼声最高的仓储模式进行讲解. 文 ...

  6. MVC5+EF6 入门完整教程12--灵活控制Action权限

    大家久等了. 本篇专题主要讲述MVC中的权限方案. 权限控制是每个系统都必须解决的问题,也是园子里讨论最多的专题之一. 前面的系列文章中我们用到了 SysUser, SysRole, SysUserR ...

  7. MVC5+EF6 入门完整教程 总目录

    本系列文章会从一个主干开始,逐渐深入,初步规划30篇.初级10篇,中级10篇,综合项目实战10篇 初级10篇 MVC5+EF6 入门完整教程10:多对多关联表更新&使用原生SQL@201505 ...

  8. MVC5 + EF6 入门完整教程1

    https://www.cnblogs.com/miro/p/4030622.html 第0课 从0开始 ASP.NET MVC开发模式和传统的WebForm开发模式相比,增加了很多"约定& ...

  9. MVC5 + EF6 入门完整教程(转载)--01

    MVC5 + EF6 入门完整教程   第0课 从0开始 ASP.NET MVC开发模式和传统的WebForm开发模式相比,增加了很多"约定". 直接讲这些 "约定&qu ...

随机推荐

  1. IOS UITableview代理方法总结

    tableview的datasource代理 @required的两个数据源方法 1.返回每个 session 中 cell 的个数 - (NSInteger)tableView:(UITableVi ...

  2. Android AsyncTask分析

    ---恢复内容开始--- 因为android的UI线程是不安全的,如果你UI线程里执行一些耗时任务,很容易就导致程序崩溃.并且目前网络任务也不能够在UI线程里执行.处理这些问题除了直接写一个线程以外, ...

  3. 【转】Android选项卡置底的方法

    转载地址:http://www.oschina.net/code/snippet_163910_6092 发现很多Android应用的选项卡 都是显示在页面底部的,网上有资料:通过反射获取TabWid ...

  4. 我的Android第四章

    本章需掌握 1.连接真机的过程. 2.dx指令的作用 3.adb是什么? 4.adb有什么用(有什么好处)? 5.adb的一些常用命令 1.连接真机的过程. 需要:一部Android机.usb连接线, ...

  5. wf(六)

    前面我们都是通过WorkflowInvoker这个类来调用方法的,这种方式是很简单的,因为这是同步的而且同样的调用者调用工作流使用的线程是一样的. 另外一个调用工作流的方法是通过工作流应用程序类(Wo ...

  6. Java SE 基础:标识(zhì)符

    Java SE 基础:标识(zhì)符 一.标识符定义 标识符,就是给类.接口.方法.变量等起名字时的字符序列 二.组成规则与注意事项 1.组成规则 英文大小写字母 数组 $ 和 _ 2.注意事项 不 ...

  7. Mybatis映射文件

    Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会 ...

  8. repeater留言板[转]

    做了一个网站,其中的在线留言板块是用Repeater来显示留言的,这样可以用少的代码还实现多的功能,但是不知道怎么分页,要是留言过多就会使页面变的很长,能过查看众多网友的经验,知道用PagedData ...

  9. kali/centos 更新 java

    kali 转自:http://blog.sina.com.cn/s/blog_5736d8870102w15u.html 墙内的论坛上和博客上有很多这样的文章了,不过一般过程都很复杂,让人看的头晕眼花 ...

  10. c++并发练习---生产者消费者模型

    问题:有一个生产者,多个消费者,生产者每生产一个,放入队列,多个消费者顺序从队列中取出数据,打印最终结果. 分析:首先这题,我本意应该设计成如下模型:生产者单开一个线程,向队列中放入数据,而消费者在锁 ...