注:例子来自微软Web API官网(https://www.asp.net/web-api/overview/data/using-web-api-with-entity-framework/part-1),也有加入自己的一点体会。

一、创建一个MVC项目,选择Web API类型的MVC,命名为BookService:

二、创建Mode和Controller:

在Models文件夹下面创建两个Model,分别是Author.cs和Book.cs;

  1)、其中Author的定义如下:

    

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations; namespace BookService.Models
{
public class Author
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
}

  2)、Book的定义如下:

  

using System.ComponentModel.DataAnnotations;

namespace BookService.Models
{
public class Book
{
public int Id { get; set; }
[Required]
public string Title { get; set; }
public int Year { get; set; }
public decimal Price { get; set; }
public string Genre { get; set; } // Foreign Key
public int AuthorId { get; set; }
// Navigation property
public Author Author { get; set; }
}
}

3)、插入小知识点----POCO:

  (1)、概念:所谓的POCO就是 pure old C# object 的缩写,翻译过来就是“纯洁老式的C#对象”,不过太拗口了,所以现在更多的称它为“简单C#对象”。

      含义:POCO的内在含义是指一个类不曾继承或者实现任何类和接口,也没有被其它框架侵入的C#对象。就是最原生态的C#对象,我的理解是它是一个“光棍”。

  (2)、意义:简单、灵活、易扩展。我们定义的POCO在后面使用的用于逻辑层的DTO(Data Transfer Object)以及用于UI显示的VO(View Object)都是以此为基础的。

三、添加API Controller,在控制器的选择当中选择 “包含操作的Web API(使用EF)”,这样子它会帮我们生成增删改查的操作。

选择之后会蹦出如下弹出框要求对控制器进行设置:

设置的话就按照上面要求的来做就行。下面进行解释:

A、模型类的选择:下拉选择,是为哪一个Model创建控制器就选择哪一个;

B、数据上下文,这个是用来创建Context文件的,这个文件是Model与数据库交互的一个门户,是对数据操作的一个集合,所有的Model都在这个类里面进行管理,我理解成是中介。添加的方式就是点击右侧的“+”然后再弹出框中点击确定就OK了。就是选择默认的名字就好了。

C、 选择异步的控制器操作,异步操作方法通常用于长时间运行的、非 CPU 绑定的请求操作方法,在这个小例子当中实际上并不是必须的。(我对这个其实还不懂,今后会好好去搞明白,索性这个异步在目前对于例子也不重要,所以可以先不用管)

D、控制器名称,这个建议是使用默认的,这个命名是很规范的,使用了REST API的设计原则,对于资源命名使用的是名词,而且是复数形式Books而不是单数形式Book,很规范。

点击 “添加” 之后会生成两个文件BooksController.cs控制器(在controller文件夹中)和BookServiceContext.cs上下文文件(在Models文件夹中)。

注:如果是跟着上面的步骤做的话其实是无法创建控制器的,因为EF是ORM框架,是根据反射进行创建的,也就是说它是需要程序集的,因此在创建使用EF的控制器之前需要进行编译,之后才可以创建成功。在这里才进行说明是个人觉得犯错才记得牢(*_*).

BooksController.cs文件主要包含对Book.cs实体类的CRUD操作,而BookServiceContext.cs包含了对Book.cs实体的注册。打开的话就可以看到。

接下来该做的就是按照上面的步骤创建Author.cs实体的控制器。

三、创建数据库,完成EF的映射:

1、添加Migration:生成一下-->在VS中选择工具-->NuGet包管理器-->Nuget程序管理控制台--->输入命令:Enable-Migrations

  效果: 在项目之下创建一个文件夹Migration,里面有一个配置文件Configuration.cs。

2.打开Configuration.cs文件,添加代码(用途是初始化数据库当中的数据),代码如下:

protected override void Seed(BookService.Models.BookServiceContext context)
{
context.Authors.AddOrUpdate(x => x.Id,
new Author() { Id = , Name = "Jane Austen" },
new Author() { Id = , Name = "Charles Dickens" },
new Author() { Id = , Name = "Miguel de Cervantes" }
); context.Books.AddOrUpdate(x => x.Id,
new Book() { Id = , Title = "Pride and Prejudice", Year = , AuthorId = ,
Price = 9.99M, Genre = "Comedy of manners" },
new Book() { Id = , Title = "Northanger Abbey", Year = , AuthorId = ,
Price = 12.95M, Genre = "Gothic parody" },
new Book() { Id = , Title = "David Copperfield", Year = , AuthorId = ,
Price = , Genre = "Bildungsroman" },
new Book() { Id = , Title = "Don Quixote", Year = , AuthorId = ,
Price = 8.95M, Genre = "Picaresque" }
);
}

seed方法是用于为数据库设置初始值的,一般在开发项目的时候我们不使用这个方法,这个例子只是为了为数据库添加数据才使用的。

3、继续在Nuget程序包控制台输入指令:

Add-Migration Initial
Update-Database
分析:
Add-Migration Initial:生成文件; Update-Database:这个方法会创建数据库,当Model改动的时候,需要再次运行上面两个指令进行数据库的更新操作(可以想见,这个就是使用了Migration的好处:不需要再
重新创
建EF,不会丢失数据)。
注:在这一步的时候我出了一个错误:根本无法创建数据库成功,后来找到原因,因为我使用的是VS自带的LocalDB,生成的实例名是Data Source=(localdb)\MSSQLLocalDB
(在web.config中),这个实例名是SQL Express2014的,而我安装的是SQl Express 2012,这样子的话就会出现问题,需要把实例名改成Data Source=(localdb)\v11.0,
那么问题就解决了。个人感觉这是一个问题,微软的VS无法检测到我们安装的是哪一个版本的SQL Exepress. 让我们来看看数据库:
4、创建DTO(Data Transfer Object):
先来说说DTO的优点:
1)、克服对数据库的重复调用;
2)、隐藏不想让用户知道的数据库表规则,即隐藏一些字段,防止数据库规则泄露;
3)、减少一些属性(字段)的调用降低服务器负荷;
4)、减少数据库中表的对象嵌套,即方便用户使用数据;
5)、避免over posting(不懂这个怎么翻译呀);
6)、解耦合(数据层和业务逻辑层之间解耦)。 四、修改自动生成的BooksController中的GetBooks()、GetBook(int id)和PostBook()方法。
// GET api/Books
public IQueryable<BookDTO> GetBooks()
{
var books = from b in db.Books
select new BookDTO()
{
Id = b.Id,
Title = b.Title,
AuthorName = b.Author.Name
}; return books;
} // GET api/Books/5
[ResponseType(typeof(BookDetailDTO))]
public async Task<IHttpActionResult> GetBook(int id)
{
var book = await db.Books.Include(b => b.Author).Select(b =>
new BookDetailDTO()
{
Id = b.Id,
Title = b.Title,
Year = b.Year,
Price = b.Price,
AuthorName = b.Author.Name,
Genre = b.Genre
}).SingleOrDefaultAsync(b => b.Id == id);
if (book == null)
{
return NotFound();
} return Ok(book);
} [ResponseType(typeof(Book))]
public async Task<IHttpActionResult> PostBook(Book book)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
} db.Books.Add(book);
await db.SaveChangesAsync(); // New code:
// Load author name
db.Entry(book).Reference(x => x.Author).Load(); var dto = new BookDTO()
{
Id = book.Id,
Title = book.Title,
AuthorName = book.Author.Name
}; return CreatedAtRoute("DefaultApi", new { id = book.Id }, dto);
}

五、创建UI和写Script脚本,显示数据:

注:这一步和官网的是不一样的,如果看官想看的话可以自行到官网查看:https://www.asp.net/web-api/overview/data/using-web-api-with-entity-framework/part-6

官网使用的是Knockout.js。公司这边已经不使用Knockout.js,所以我是使用angular.js来写的。

1、先上HTML代码,把View文件夹下的子文件夹下面的Home中的index替换成如下代码(要自己引用angular.js):

<style type="text/css">
h1,h2,h3,html,div{
margin:0;
padding:0; }
#books {
border: 2px solid #000000;
padding: 20px;
width: 350px;
font-size: 18px;
margin:10px;
float:left;
}
#addBlock{
border: 2px solid #000000;
padding: 20px;
width: 350px;
font-size: 18px;
margin:10px;
float:left;
} #details{
border: 2px solid #000000;
padding: 20px;
width: 350px;
font-size: 18px;
margin:10px;
float:left;
}
#edit{
border: 2px solid #000000;
padding: 20px;
width: 350px;
font-size: 18px;
margin:10px;
clear:both;
}
/*div{float:left;
margin:20px;
}*/
</style> <div ng-app="First" ng-controller="firstController"> <!--base message-->
<div id="books">
<h1>Books</h1>
<p ng-repeat="x in baseMessage"> <label ng-bind="x.Title+': '+x.AuthorName"></label>
<a href="#" ng-click="detail(x.Id)">Details</a>
<a href="#" ng-click="delete(x.Id)">Delete</a>
</p>
</div> <!--detail message-->
<div id="details">
<h1>Details</h1>
<label>Author</label> <label>{{": "+Author}}</label><br />
<label>Title</label> <label>{{": "+Title}}</label><br />
<label>Year</label> <label>{{": "+Year}}</label><br />
<label>Genre</label> <label>{{": "+Genre}}</label><br />
<label>Price</label> <label>{{": "+Price}}</label><br />
</div>
<!--add block-->
<div id="addBlock">
<h1>Add Book</h1>
<label>Author</label><select id="Author" ng-options="item as item.AuthorName for item in baseMessage" ng-model="selectedAuthor"></select><br />
@*@Html.DropDownList("Author", new List<SelectListItem>(), new { ng_options = "item as item.AuthorName for item in baseMessage", ng_model = "selected" });*@
<!--Why???????-->
<label>Title</label><input type="text" id="Title" /> <br />
<label>Year</label> <input type="text" id="Year" /><br />
<label>Genre</label> <input type="text" id="Genre" /><br />
<label>Price</label> <input type="text" id="Price" /><br />
<input type="button" value="Add" ng-click="AddBook(selectedAuthor)"/>
</div>
<hr />
<!--Edit block-->
<div id="edit">
<h1>Modify Books</h1>
<label>Book:</label><select id="Author" ng-options="item as item.Title for item in baseMessage" ng-model="selectedBook"></select><br />
<label>Title:</label><input type="text" id="titleModify" /> <br />
<label>Year:</label> <input type="text" id="yearModify" /><br />
<label>Genre:</label> <input type="text" id="genreModify" /><br />
<label>Price:</label> <input type="text" id="priceModify" /><br />
<input type="button" value="Modify" ng-click="ModifyBook(selectedBook)" />
</div>
</div>

2、新建一个js文件,引用到index,js文件写的是angular代码,如下:

var app = angular.module("First", []);
app.controller("firstController", function ($scope, $http) {
var message = new Array();
var selectAuthor = new Array();
$http({
method: "GET",
url: "/api/Books/"
}).then(function (data) {
angular.forEach(data.data, function (value, key) {
message.push(value);
selectAuthor.push(value.AuthorName);
})
$scope.baseMessage = message;
$scope.selectAuthors = selectAuthor;
$scope.selected = $scope.baseMessage[0];
}) $scope.detail = function detail(id) {
$http.get("/api/Books/" + id).then(function (data) {
$scope.Author = data.data.AuthorName;
$scope.Title = data.data.Title;
$scope.Year = data.data.Year;
$scope.Genre = data.data.Genre;
$scope.Price = data.data.Price;
});
} $scope.delete = function (id) {
$http.delete("api/Books/" + id).then(function () {
alert("OK,You have already delete it!");
})
} $scope.AddBook = function (selectedAuthor) {
//alert(selected.Id);
var Title = $("#Title").val();
var Year = $("#Year").val();
var Genre = $("#Genre").val();
var Price = $("#Price").val();
var book = {
AuthorId: parseInt(selectedAuthor.Id),
Title: Title,
Year: parseInt(Year),
Genre: Genre,
Price: Price
}
$http.post(
"/api/Books/", book).success(function () {
alert("Add Sucess!");
})
} $scope.ModifyBook = function (selectedModify) {
var id = selectedModify.Id;
var AuthorId = 1;
authorId(id);
function authorId(id) {
$http.get("/api/Books/" + id).then(function (data) {
AuthorId = data.data.AuthorId; var Title = $("#titleModify").val();
var Year = $("#yearModify").val();
var Genre = $("#genreModify").val();
var Price = $("#priceModify").val();
var book = {
AuthorId: AuthorId,
Id: parseInt(selectedModify.Id),
Title: Title,
Year: parseInt(Year),
Genre: Genre,
Price: Price
}
//$http.put("/api/Books/" + selectedModify.Id, book,function () {
// alert("OK,You have already modify it (*_*) ~");
//});
$http({ method: "PUT", url: "/api/Books/" + selectedModify.Id, data: { "id": selectedModify.Id, "book": book } }).then(function () {
alert("OK,You have already modify it (*_*) ~");
}); });
}
}
});

3、生成解决方案然后运行就会有结果了。

注:博主有强迫症,一个博文不喜欢写太长,所以对于angular代码的解析就放在其他博文里面http://www.cnblogs.com/heisehenbai/p/Angular.html


												

Web API 之CRUD的更多相关文章

  1. Asp.Net Web API 2(CRUD操作)第二课

    Asp.Net Web API 2(CRUD操作)第二课 Asp.Net Web API 导航   Asp.Net Web API第一课:入门http://www.cnblogs.com/aehyok ...

  2. ASP.NET Web API 基本操作(CRUD)

    上一篇介绍了ASP.NET Web API的基本知识和原理,这一篇我们通过一个更直观的实例,对产品进行CRUD操作(Create/Read/Update/Delete)来继续了解一下它的基本应用. 创 ...

  3. ASP.NET Core Web API Cassandra CRUD 操作

    在本文中,我们将创建一个简单的 Web API 来实现对一个 “todo” 列表的 CRUD 操作,使用 Apache Cassandra 来存储数据,在这里不会创建 UI ,Web API 的测试将 ...

  4. 在ASP dot Net Core MVC中用Controllers调用你的Asp dotnet Core Web API 实现CRUD到远程数据库中,构建你的分布式应用(附Git地址)

    本文所有的东西都是在dot Net Core 1.1环境+VS2017保证测试通过. 本文接着上次文章接着写的,不了解上篇文章的可能看着有点吃力.我尽量让大家都能看懂.这是上篇文章的连接http:// ...

  5. 在Core环境下用WebRequest连接上远程的web Api 实现数据的简单CRUD(续)

    这篇博客是上篇博客的续写,上篇博客用的是HttpClient取远程数据,用WebRequest提交,更新,删除数据.上篇本来想全文都用httpClient,可是当时无论如何也实现不了数据的提交,于是换 ...

  6. ASP。NET Core Blazor CRUD使用实体框架和Web API

    下载source code - 1.7 MB 介绍 *请查看我的Youtube视频链接来学习ASP.NET Core Blazor CRUD使用实体框架和Web API. 在本文中,我们将了解如何为A ...

  7. 【ASP.NET Web API教程】2.3 与实体框架一起使用Web API

    原文:[ASP.NET Web API教程]2.3 与实体框架一起使用Web API 2.3 Using Web API with Entity Framework 2.3 与实体框架一起使用Web ...

  8. 返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API

    原文:返璞归真 asp.net mvc (10) - asp.net mvc 4.0 新特性之 Web API [索引页][源码下载] 返璞归真 asp.net mvc (10) - asp.net ...

  9. 通过HttpClient 调用ASP.NET Web API

    在前面两篇文章中我们介绍了ASP.NET Web API的基本知识和原理,并且通过简单的实例了解了它的基本(CRUD)操作.我们是通过JQuery和Ajax对Web API进行数据操作.这一篇我们来介 ...

随机推荐

  1. 设计模式--组合模式Composite(结构型)

    一.概念 组合模式允许你将对象组合成树形结构来表现"整体/部分"层次结构.组合能让客户以一致的方式处理个别对象以及对象组合. 二.UML图 1.Component(对象接口),定义 ...

  2. shell:遍历目录和子目录的所有文件

    #!/bin/bash function getdir(){ ` do dir_or_file=$"/"$element if [ -d $dir_or_file ] then g ...

  3. web项目中各种路径的获取

    以工程名为/DemoWeb为例: 访问的jsp为:http://localhost:8080/DemoWeb/test/index.jsp 1 JSP中获得当前应用的相对路径和绝对路径 (1)得到工程 ...

  4. Java获取用户ip

    /** * 获取客户端ip地址(可以穿透代理) * * @param request * @return */ public static String getRemoteAddr(HttpServl ...

  5. sql 数据库结构导出到文件

    SELECT 表名 = Case When A.colorder= Then D.name Else '' End, 表说明 = Case When A.colorder= Then isnull(F ...

  6. CentOS7 编译安装 nginx-1.10.0

    对于NGINX 支持epoll模型 epoll模型的优点 定义: epoll是Linux内核为处理大批句柄而作改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著的 ...

  7. CSS 清除默认样式

    通常有以下几句就够了: *{margin:0;padding:0} li{list-style:none} img{vertical-align:top;border:none} 如果你想写全也可以: ...

  8. MFC 滑动条的重绘

    MFC自带的滑动条的样子是这样的. 比较难看,所以需要重绘下,重绘后的样子是这样的. 代码如下: CustomSliderCtr.h #pragma once // CCustomSliderCtr ...

  9. Jquery知识点

    Jquery $代表选择器 JS 选取元素 操作内容 操作属性 操作样式 <div id="aa" style="width:100px; height:100px ...

  10. myeclipse maven 安装

    myeclipse 上安装 Maven3   环境准备: JDK 1.6.45 Maven 3.0.5 myeclipse 8.5 安装 Maven 之前要求先确定你的 JDK 已经安装配置完成.Ma ...