MVC5+EF6 入门完整教程四

MVC5+EF6 入门完整教程四
原文:MVC5+EF6 入门完整教程四

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

    var 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

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

好了,今天就到这里。

欢迎大家多多评论,让下一篇文章更好 :)

posted on 2014-11-04 16:46 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/4074083.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/459933.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android js调试

http://blog.allenm.me/ 其他平台去这篇文章看 1 //js调试调试功能支持4.4版本以上的2 if(Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {3 WebView.setWebContentsDebuggingEnabled(true);4 }5 //j…

python 比赛成绩预测_利用 Python 预测英雄联盟胜负,分析了 5 万多场比赛才得出的数据!值得,涨知识了!...

Mika 来源 | 头图 |CSDN自东方IC今天教大家用Python预测英雄联盟比赛胜负。Show me data&#xff0c;用数据说话今天我们聊一聊 Python预测LOL胜负目前&#xff0c;英雄联盟S10全球总决赛正在火热进行中&#xff0c;最终决赛于10月31日在浦东足球场举行。作为当下最火热的电竞赛…

服务器2003蓝屏A5修复,0x000000a5蓝屏完美解决方法 Win7

0x000000a5蓝屏怎么办&#xff1f;在Win7系统下遭遇开机时出现蓝屏代码0x000000a5非常多&#xff0c;由于根据代码我们并不能分析出故障原因&#xff0c;那么只能求助于网络上大家分享的经验了&#xff0c;下面小编给大家分享下0x000000a5蓝屏完美解决方法&#xff0c;适用于Wi…

能设值多个rowkey吗_顶楼送了露台,悄悄搭建阳光房,偏偏我家露台多个帽子,能拆吗?...

你们有没有发现现在楼顶上都会有几个这样的“帽子"&#xff0c;呼呼直转&#xff0c;但大多数人并不是很明白这个东西是干嘛用的。昨天有网友私信&#xff1a;小区顶楼露台上这个不锈钢帽子可以加高吗&#xff1f;感觉每次去楼顶都会闻到一股油烟味。业主表示自己是住在顶…

金山云服务器内网带宽,金山云-文档中心-配置弹性网卡

本文为您介绍绑定弹性网卡后虚机中如何配置弹性网卡。挂载辅网卡后&#xff0c;Windows操作系统主机即可正常使用&#xff0c;不需要额外操作。如果实例使用以下几种镜像&#xff0c;则可以跳过网卡手动配置&#xff0c;直接进行路由配置。CentOS 7.6 64位CentOS 7.7 64位CentO…

Atom飞行手册翻译: 2.7 ~ 2.10

自动补全 如果你仍旧希望节约一些打字时间&#xff0c;Atom自带简单的自动补全功能。 通过使用ctrl-space&#xff0c;自动补全工具可以让你看到并插入可选的完整单词。 通常&#xff0c;自动补全工具会浏览当前打开的整个文档&#xff0c;寻找匹配你开始打出来的单词。 如果你…

Flash游戏开发实战(一)

我不得不承认&#xff0c;我不是植物大战僵尸的骨灰玩家&#xff0c;所以&#xff0c;如果你发现这个系列的教程有什么地方错误的&#xff0c;请告诉我。 定义游戏的主要结构 植物大战僵给了我们很好的视觉和感觉上的享受。你得保护你的房子以免被吃脑的僵尸入侵&#xff0c;这…

如何做相册_手机里的照片太多,不得已只能删除?那就试试制作电子相册吧

许多人都喜欢使用手机拍照&#xff0c;这也就导致自己手机相册中保存的照片越来越多&#xff0c;到后面想要再拍照片的话&#xff0c;就不得不删除之前的照片&#xff0c;如何解决这个办法呢&#xff1f;那就试试用【迅捷视频转换器】将其制作成电子相册吧。制作电子相册打开软…

python windows窗口置顶_想用Python编程却不知如何下手?一篇搞定编程准备工作

导读&#xff1a;为了简化Python编程的学习难度&#xff0c;开发过程中的工具、环境尽量使用同一套&#xff0c;此后所有的编程环境都以Windows系统下Python3.8为准&#xff0c;代码编辑器及IDE(集成开发环境)使用VS Code。目的很简单&#xff0c;就是为了让所有的讲解和学习集…

小程序 ajax 加载,小程序实战-小程序网络请求异步加载

最初看到小程序的网络请求的时候,尤其是演示示例中&#xff0c;userInfoReadyCallback这个函数更是一头雾水。其实并不怎么理解.一直很费解.网上各路大侠都有解释&#xff0c;但是就是&#xff0c;不知道是怎么个顺序,而我也是个对程序执行流程很关注的人,现在把我的心得分享给…

华为手机怎么强制关机_华为忘记锁屏密码怎么办?多品牌手机通用解锁密码

手机忘记登陆密码怎么办&#xff1f;下面小编介绍几种方法&#xff0c;轻松解开那些忘记锁屏密码的手机&#xff0c;第一种方法可能大家还知道&#xff0c;但第二种方法肯定没几个人知道。1、手机原地复活这种方法是可以解决锁屏密码的问题&#xff0c;但也一并把手机上所有的数…

HTML5与搜索引擎优化[转载]

原文&#xff1a;http://lusongsong.com/reed/398.html 我觉得HTML5的兴起完全是因为iPhone和iPad&#xff0c;自从Adobe停止开发flash、Android4.0不支持flash后&#xff0c;我觉得在不久的将来HTML5会广泛应用&#xff0c;而且HTML4已经10年没更新了。 HTML5与HTML4代码结构对…

如何让 zend studio 10 识别 Phalcon语法并且进行语法提示

让 zend studio 10 识别 Phalcon语法并且进行语法提示https://github.com/rogerthomas84/PhalconPHPDoc下载解压后&#xff0c;把里面 phalcon 整个目录复制到 workspace 的C:\Documents and Settings\Administrator\Zend\workspaces\DefaultWorkspace\.metadata\.plugins\org.…

包r语言_R语言入门之寻找你的R包

关于寻找目标R包&#xff0c;一般可以在官网利用关键词搜索即可获得相关信息&#xff0c;不过米老鼠在这里想给大家介绍一个特别的R包&#xff0c;它可以帮助你寻找你想要的理想R包。不过&#xff0c;在正式讲解&#xff0c;我想和大家提醒一下安装R包的注意事项&#xff1a; &…

NOI2011 智能车比赛

SPFA。 我们关键是要找到关键点&#xff0c;包括起点&#xff0c;终点&#xff0c;和相邻矩形接触线段的上端点和下端点&#xff08;如图有红色圈住的点为关键点&#xff09;。 我们要做的就是在这些关键点之间连边。 我们把这些关键的点拿出来: 其实就是一些竖直的线段。 除了…

ftp服务器上传文件权限设置,ftp服务器 上传文件权限设置

ftp服务器 上传文件权限设置 内容精选换一换华为云对象存储服务帮助中心&#xff0c;为用户提供产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题、视频帮助等技术文档&#xff0c;帮助您快速上手使用对象存储服务。云数据库RDS服务上的MySQL在使用上有一…

悼念512汶川大地震遇难同胞——一定要记住我爱你

Problem Description当抢救人员发现她的时候&#xff0c;她已经死了&#xff0c;是被垮塌下来的房子压死的&#xff0c;透过那一堆废墟的的间隙可以看到她死亡的姿势&#xff0c;双膝跪着&#xff0c;整个上身向前匍匐着&#xff0c;双手扶着地支撑着身体&#xff0c;有些象古人…

获取当前ip_教程丨WIN10系统下设置固定IP或动态IP

无论是电脑、手机或其他一切电子设备&#xff0c;如果需要上网&#xff0c;它就必须有一个IP地址&#xff0c;然后IP地址的获取通常又分为 动态IP(自动获取)或 静态IP(手动设置)两种模式(您所在的网络具体适用哪种模式&#xff0c;请咨询您的网络管理员&#xff1b;目前学校都是…

php实现服务器文件同步,PHPstorm配置同步服务器文件

1、配置服务器一、链接配置服务器打开菜单栏 Tools -> Deployment -> Configurationapp点击 选择 SFTP&#xff0c;并填写相关服务器信息&#xff1a;测试Type&#xff1a;链接类型&#xff0c;这里选择SFTP3dHost&#xff1a;服务器ip地址ormPort&#xff1a;端口&…

oc 实例变量可见度、方法

为什么80%的码农都做不了架构师&#xff1f;>>> ⼀、实例变量可⻅度 public 在类的外部和内部均可访问 protected(默认) 只能在该类和其⼦类内访问 private 只能在该类内访问 ⼆、⽅法&#xff08;定义、声明、调用&#xff…