3.EF 6.0 Code-First实现增删查改
或者:http://www.codeproject.com/Articles/640302/CRUD-Operations-Using-Entity-Framework-Code-Fi
系列目录:
- Relationship in Entity Framework Using Code First Approach With Fluent API【【使用EF Code-First方式和Fluent API来探讨EF中的关系】】
- Code First Migrations with Entity Framework【使用EF 做数据库迁移】
- CRUD Operations Using Entity Framework 5.0 Code First Approach in MVC【在MVC中使用EF 5.0做增删查改】
- CRUD Operations Using the Repository Pattern in MVC【在MVC中使用仓储模式,来做增删查改】
- CRUD Operations Using the Generic Repository Pattern and Unit of Work in MVC【在MVC中使用泛型仓储模式和工作单元来做增删查改】
- CRUD Operations Using the Generic Repository Pattern and Dependency Injection in MVC【在MVC中使用泛型仓储模式和依赖注入,来做增删查改】
本来不想写这篇的,因为感觉增删查改,实在是太Easy了。好了,为了巩固学习,还是继续吧:
打算实现书籍的增删查改,有两个实体,一个是Book【书籍实体】,另外一个是出版商实体【Publisher】,一个出版商可以出版很多书籍,一本书只能是由一个出版商出版。所以,书籍和出版商之间是一对多的关系。
先来看看整个项目的结构吧:

Entity实体中:
BaseEntity实体:【日期使用了数据注解,这样在显示的时候,就有格式了。】
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace EF.Entity
{
public abstract class BaseEntity
{ /// <summary>
/// ID
/// </summary>
public int ID { get; set; } /// <summary>
/// 添加时间
/// </summary>
///
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime AddedDate { get; set; } /// <summary>
/// 修改时间
/// </summary>
///
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime ModifiedDate { get; set; }
}
}
Book实体:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace EF.Entity
{
/// <summary>
/// Book实体
/// </summary>
public class Book:BaseEntity
{
/// <summary>
/// 书名
/// </summary>
public string BookName { get; set; } /// <summary>
/// 书的作者
/// </summary>
public string BookAuthor { get; set; } /// <summary>
/// 书的价格
/// </summary>
public decimal BookPrice { get; set; } /// <summary>
/// 出版商编号
/// </summary>
public int PublisherId { get; set; } /// <summary>
/// 导航属性---出版商
/// </summary>
public virtual Publisher Publisher { get; set; }
}
}
出版商实体:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace EF.Entity
{
public class Publisher:BaseEntity
{
/// <summary>
/// 出版商的名字
/// </summary>
public string PublisherName { get; set; } /// <summary>
/// 导航属性
/// </summary>
public virtual ICollection<Book> Books { get; set; }
}
}
然后在EF.Data项目中:
BookMap类:
using EF.Entity;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace EF.Data
{
public class BookMap:EntityTypeConfiguration<Book>
{
public BookMap()
{
//配置主键
this.HasKey(s => s.ID);
//配置字段
this.Property(s => s.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(s => s.BookName).HasColumnType("nvarchar").HasMaxLength().IsRequired();
// this.Property(s => s.BookAuthor).HasColumnType("nvarchar(50)").IsRequired();//注意这个和BookName字段配置的区别之处:这样写EF生成不了数据库
this.Property(s => s.BookAuthor).HasColumnType("nvarchar").HasMaxLength().IsRequired();
this.Property(s => s.BookPrice).IsRequired();
this.Property(s => s.AddedDate).IsRequired();
this.Property(s => s.ModifiedDate).IsRequired();
this.Property(s => s.PublisherId).IsRequired(); //配置关系[一个出版商可以出版很多书籍]【外键单独配置,不是必须在Property中配置,当然也可以在Property中配置】
this.HasRequired(s => s.Publisher).WithMany(s => s.Books).HasForeignKey(s => s.PublisherId).WillCascadeOnDelete(true); //配置表名字
this.ToTable("Books"); }
}
}
PublisherMap类:
using EF.Entity;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace EF.Data
{
public class PublisherMap:EntityTypeConfiguration<Publisher>
{
public PublisherMap()
{
//配置主键
this.HasKey(s => s.ID);
this.Property(s => s.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
// this.Property(s => s.PublisherName).HasColumnType("nvarchar(50)").IsRequired();//这样写,有问题,生成不了数据库
this.Property(s => s.PublisherName).HasColumnType("nvarchar").HasMaxLength().IsRequired();
this.Property(s => s.AddedDate).IsRequired();
this.Property(s => s.ModifiedDate).IsRequired(); }
}
}
出版商我这里不做增删查改,到时候手动添加几条数据进去,然后在Book的视图中,把出版商做成下拉框的样式:所以我这里额外添加一个实体:【PublisherModel实体中的构造函数里的初始化属性嗲吗,不能忘记!!!】
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace EF.Web.Models
{
public class PublisherModel
{
public PublisherModel()
{
PublisherList = new List<SelectListItem>();
} [Display(Name="PublisherName")]
public int PublisherID { get; set; } public List<SelectListItem> PublisherList { get; set; }
}
}
数据上下文类:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks; namespace EF.Data
{
public class EFDbContext:DbContext
{
public EFDbContext()
: base("name=DbConnectionString")
{ } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.BaseType != null && type.BaseType.IsGenericType
&& type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
//base.OnModelCreating(modelBuilder);
}
}
}
Ef.Data项目和Web项目中都要加上连接字符串:
<connectionStrings>
<add name="DbConnectionString" connectionString="Server=.;Database=EFCURDDB;uid=sa;Pwd=Password_1" providerName="System.Data.SqlClient"/>
</connectionStrings>
现在看看Web项目:
using EF.Data;
using EF.Entity;
using EF.Web.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc; namespace EF.Web.Controllers
{
public class BookController : Controller
{
private EFDbContext db;
public BookController()
{
db = new EFDbContext();
}
#region 列表
/// <summary>
/// 列表
/// </summary>
/// <returns></returns>
public ActionResult Index()
{
return View(db.Set<Book>().ToList());
}
#endregion #region AddBook
/// <summary>
/// 添加Book
/// </summary>
/// <returns></returns>
public ActionResult AddBook()
{
PublisherModel model = new PublisherModel();
List<Publisher> listPublisher = db.Set<Publisher>().ToList(); foreach (var item in listPublisher)
{
model.PublisherList.Add(new SelectListItem()
{
Text = item.PublisherName,
Value = item.ID.ToString() });
} ViewBag.PublishedList = model.PublisherList; return View();
} /// <summary>
/// 添加Book
/// </summary>
/// <returns></returns>
[HttpPost]
public ActionResult AddBook([Bind(Include = "BookName,BookAuthor,BookPrice,AddedDate,ModifiedDate,PublisherId")] Book model)
{
Book addBook = new Book() {
AddedDate=model.AddedDate,
BookAuthor=model.BookAuthor,
BookName=model.BookName,
BookPrice=model.BookPrice,
ModifiedDate=model.ModifiedDate,
PublisherId = Convert.ToInt32( Request["PublishedName"].ToString())
//这里因为出版商我用的是另外的Model,视图中使用模型绑定只能用一个Model,所以修改和添加只能这样搞了。 };
db.Entry(addBook).State = EntityState.Added;
db.SaveChanges();
return RedirectToAction("Index");
}
#endregion #region UpdateBook
/// <summary>
/// 修改Book
/// </summary>
/// <param name="bookId"></param>
/// <returns></returns>
public ActionResult UpdateBook(int bookId)
{
PublisherModel model = new PublisherModel();
List<Publisher> listPublisher = db.Set<Publisher>().ToList(); foreach (var item in listPublisher)
{
model.PublisherList.Add(new SelectListItem()
{
Text = item.PublisherName,
Value = item.ID.ToString() });
} ViewBag.PublishedList = model.PublisherList; Book bookModel = db.Set<Book>().Where(s => s.ID == bookId).FirstOrDefault();
return View(bookModel);
} /// <summary>
/// 修改Book
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost]
public ActionResult UpdateBook([Bind(Include = "ID,BookName,BookAuthor,BookPrice,AddedDate,ModifiedDate,PublisherId")] Book model) //注意这里一定别忘记绑定 ID列哦
{
Book bookModel = db.Set<Book>().Where(s => s.ID == model.ID).FirstOrDefault(); if (bookModel != null)
{
Book updatemodel = new Book() {
AddedDate = model.AddedDate,
BookAuthor = model.BookAuthor,
ID = model.ID,
ModifiedDate = model.ModifiedDate,
BookName = model.BookName,
BookPrice = model.BookPrice,
PublisherId = Convert.ToInt32(Request["PublishedName"].ToString())//这里因为出版商我用的是另外的Model,视图中使用模型绑定只能用一个Model,所以修改和添加只能这样搞了。
};
db.Entry(bookModel).CurrentValues.SetValues(updatemodel); //保存的另外一种方式
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
return View(model);
} #region 保存的方式二
//db.Entry(model).State = EntityState.Modified;
//db.SaveChanges();
//return RedirectToAction("Index");
#endregion
}
#endregion #region DeleteBook
public ActionResult DeleteBook(int bookId)
{
Book model = db.Set<Book>().Where(s => s.ID == bookId).FirstOrDefault();
return View(model);
} [HttpPost]
public ActionResult DeleteBook(int bookId, FormCollection form)
{
Book model = db.Set<Book>().Where(s => s.ID == bookId).FirstOrDefault();
db.Entry(model).State = EntityState.Deleted;
db.SaveChanges();
return RedirectToAction("Index");
}
#endregion }
}
视图代码,我使用MVC模板生成:【适当做修改】
AddBook视图:
@model EF.Entity.Book
@{
ViewBag.Title = "AddBook";
}
<h2>AddBook</h2>
@using (Html.BeginForm("AddBook","Book",FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Book</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.AddedDate, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.AddedDate, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.AddedDate, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ModifiedDate, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ModifiedDate, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ModifiedDate, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.BookName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.BookName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.BookName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.BookAuthor, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.BookAuthor, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.BookAuthor, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.BookPrice, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.BookPrice, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.BookPrice, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PublisherId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("PublishedName", ViewData["PublishedList"] as List<SelectListItem>)
@*@Html.EditorFor(model => model.PublisherId, new { htmlAttributes = new { @class = "form-control" } })*@
@Html.ValidationMessageFor(model => model.PublisherId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
UpdateBook视图:
@model EF.Entity.Book
@{
ViewBag.Title = "UpdateBook";
}
<h2>UpdateBook</h2>
@using (Html.BeginForm("UpdateBook","Book",FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Book</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.ID)
<div class="form-group">
@Html.LabelFor(model => model.AddedDate, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.AddedDate, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.AddedDate, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ModifiedDate, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.ModifiedDate, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.ModifiedDate, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.BookName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.BookName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.BookName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.BookAuthor, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.BookAuthor, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.BookAuthor, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.BookPrice, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.BookPrice, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.BookPrice, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PublisherId, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("PublishedName", ViewData["PublishedList"] as List<SelectListItem>)
@*@Html.EditorFor(model => model.PublisherId, new { htmlAttributes = new { @class = "form-control" } })*@
@Html.ValidationMessageFor(model => model.PublisherId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
注意:这里我只是把有改动的视图贴了出来,其他的视图,根据MVC模板生成之后,就不用管了。
@model IEnumerable<EF.Entity.Book>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
@Html.ActionLink("Create New", "AddBook")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.AddedDate)
</th>
<th>
@Html.DisplayNameFor(model => model.ModifiedDate)
</th>
<th>
@Html.DisplayNameFor(model => model.BookName)
</th>
<th>
@Html.DisplayNameFor(model => model.BookAuthor)
</th>
<th>
@Html.DisplayNameFor(model => model.BookPrice)
</th>
<th>
@Html.DisplayNameFor(model => model.PublisherId)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.AddedDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.ModifiedDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.BookName)
</td>
<td>
@Html.DisplayFor(modelItem => item.BookAuthor)
</td>
<td>
@Html.DisplayFor(modelItem => item.BookPrice)
</td>
<td>
@Html.DisplayFor(modelItem => item.PublisherId)
</td>
<td>
@Html.ActionLink("Edit", "UpdateBook", new { bookId = item.ID }) |
@Html.ActionLink("Details", "DetailsBook", new { bookId = item.ID }) |
@Html.ActionLink("Delete", "DeleteBook", new { bookId = item.ID })
</td>
</tr>
}
</table>
效果图:




总结:1.下拉框实体中,构造函数初始化语句不能忘记。
2.修改的方式,有新变化看代码;
3.模型绑定的时候,特别要注意,Bind的字段,修改的时候,Bind字段ID不能少。
3.EF 6.0 Code-First实现增删查改的更多相关文章
- EF各版本增删查改及执行Sql语句
自从我开始使用Visual Studio 也已经经历了好几个版本了,而且这中间EF等框架的改变也算是比较多的.本篇文章记录下各个版本EF执行Sql语句和直接进行增删查改操作的区别,方便自己随时切换版本 ...
- EF增删查改加执行存储过程和sql语句,多种方法汇总
ActionUrl c = new ActionUrl() { ActionName="test", RequestUrl="/123/123", SubTim ...
- 6.在MVC中使用泛型仓储模式和依赖注入实现增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...
- 4.在MVC中使用仓储模式进行增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-using-the-repository-pattern-in-mvc/ 系列目录: ...
- 5.在MVC中使用泛型仓储模式和工作单元来进行增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...
- 极极极极极简的的增删查改(CRUD)解决方案
去年这个时候写过一篇全自动数据表格的文章http://www.cnblogs.com/liuyh/p/5747331.html.文章对自己写的一个js组件做了个概述,很多人把它当作了一款功能相似的纯前 ...
- 在MVC中使用泛型仓储模式和工作单元来进行增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pat ...
- 在MVC中使用泛型仓储模式和依赖注入实现增删查改
标签: 原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository ...
- MongoDB数据库(二):增删查改
MongoDB数据库的增删查改 1.插入数据 语法: db.集合名称.insert(document) db.table_name.insert({name:'gj',gender:1}) db.ta ...
随机推荐
- .net 分布式架构之业务消息队列
开源QQ群: .net 开源基础服务 238543768 开源地址: http://git.oschina.net/chejiangyi/Dyd.BusinessMQ ## 业务消息队列 ##业务消 ...
- [C#] C# 知识回顾 - 特性 Attribute
C# 知识回顾 - 特性 Attribute [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5911289.html 目录 特性简介 使用特性 特性 ...
- Asp.Net WebApi核心对象解析(上篇)
生活需要自己慢慢去体验和思考,对于知识也是如此.匆匆忙忙的生活,让人不知道自己一天到晚都在干些什么,似乎每天都在忙,但又好似不知道自己到底在忙些什么.不过也无所谓,只要我们知道最后想要什么就行.不管怎 ...
- 深入浅出JavaScript之原型链&继承
Javascript语言的继承机制,它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instanc ...
- JavaWeb——Listener
一.基本概念 JavaWeb里面的listener是通过观察者设计模式进行实现的.对于观察者模式,这里不做过多介绍,大概讲一下什么意思. 观察者模式又叫发布订阅模式或者监听器模式.在该模式中有两个角色 ...
- 让你从零开始学会写爬虫的5个教程(Python)
写爬虫总是非常吸引IT学习者,毕竟光听起来就很酷炫极客,我也知道很多人学完基础知识之后,第一个项目开发就是自己写一个爬虫玩玩. 其实懂了之后,写个爬虫脚本是很简单的,但是对于新手来说却并不是那么容易. ...
- ubuntu14.04下安装node.js
在网上查了下,起初是下载了一个node-v0.12.7-linux-x64.tar.gz,解压在/home/node路径下,然后在/etc/profile中添加如下命令: export NODE_HO ...
- 《深入理解Java虚拟机》虚拟机性能监控与故障处理工具
上节学习回顾 从课本章节划分,<垃圾收集器>和<内存分配策略>这两篇随笔同属一章节,主要是从理论+实验的手段来讲解JVM的内存处理机制.好让我们对JVM运行机制有一个良好的概念 ...
- Thinking in Unity3D
关于<Thinking in Unity3D> 笔者在研究和使用Unity3D的过程中,获得了一些Unity3D方面的信息,同时也感叹Unity3D设计之精妙.不得不说,笔者最近几年的引擎 ...
- .NET 基础一步步一幕幕[方法、结构、枚举]
方法.结构.枚举 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值,写void 方法名:P ...