OData的增加和删除改查爱博体育app手机版

对于在ASP.NET WebAPI中怎么使用OData,
曾经在自个儿前面包车型客车日志中的表达,

背景解释

原稿来自于https://www.codeproject.com/Tips/1074608/CRUD-in-ASP-NET-MVC-using-WebAPI-with-AngularJS

代码DEMO:https://www.codeproject.com/KB/scripting/1074608/AngularJS\_Demo.zip

先是次翻译工夫文章,多谢谷歌(Google)翻译~~

CRUD是指在做总结管理时的扩张(Create)、查询(Retrieve)(重新得到数据)、更新(Update)和删除(Delete)多少个单词的首字母简写。首要被用在描述软件系统中数据库大概持久层的基本操作成效。

那篇小说将帮忙初学者在ASP.NET MVC 5中应用具有脚本语言的WebAPI 2
、AngularJS和MS SQL 二零零六Sportage2数据库实现CRUD操作。

在ASP.NET Web API中使用OData

介绍

如你所知,AngularJS是单页应用程序开采中最风靡的JavaScript框架之一。
您能够应用Angular举办扦插,更新,删除和寻觅操作。
本文将演示怎么着采取Angular、MVC5和WebAPI2实行CRUD操作。
有经验的开拓职员会发觉那篇小说极度基本,是的,那篇小说是从初学者的角度写的,所以笔者尽大概保持简洁易懂。

在那么些示例中。作者新建了二个Order的实业,
在后边一个接纳Angular举行追加,删除,修改,查询,分页

下边是Order的实业结构,有No,Total,Data3个属性
public class Order
{
    public int Id { get; set; }
    public string No { get; set; }
    public decimal Total { get; set; }
    public DateTime Date { get; set; }
}
下一场大家对其进行OData路由进行注册
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Order>(“Orders”);
config.MapODataServiceRoute(“ODataRoute”, null,
builder.GetEdmModel());

再创建OData的WebAPI Controller

下一场我们用Code First生成到数据库
如此这般。大家就足以对基进行测量试验,(这里测验用的是Postman工具)
1。增添二个Order
爱博体育app手机版 1
查询那些Order
爱博体育app手机版 2
修改那几个Order
爱博体育app手机版 3
删去这么些Order
爱博体育app手机版 4
一切都以寻常运转

接下去我们创设前端AngularJS
始于大家在页面援引AngularJS
<script src=”Scripts/angular.js”></script>
接下来申宾博个Module
var mainModule = angular.module(“MainApp”, []);
因为WebAPI大家能够把她当做二个服务,所以大家得以如此写

//申明Module

var mainModule = angular.module("MainApp", []);

//创建Order的增删改查Angular服务

mainModule.service("Order", ["$rootScope", "$http", function ($rootScope, $http) {

//page:当前页码

//filter:查询条件

var service = { orders: [], page: 1, filter: "" };

//根据页码,查询条件,拿到当前的Orders集合

service.getOrders = function () {

//OData可以通过odata/Orders?$skip=分页跳过的记录数&$filter=查询条件

//通过这样的GET请求,可以拿到当前查询条件下的第几页数据

$http.get("odata/Orders?$skip=" + ((this.page - 1) * 3).toString() + this.filter)

.success(function (data, status, headers, config) {

service.orders = data.value;

//setvice.nextLink = data["@odata.nextLink"];

$rootScope.$broadcast('orders.update');

})

.error(function (data, status, headers, config) { });

};

//增加Order,传入Order对象Post到odata/Orders

service.addOrder = function (order) {

$http.post("odata/Orders", order)

.success(function (data, status, headers, config) {

service.orders.push(data);

})

.error(function (data, status, headers, config) { });

};

//删除Order,用Delete请求odata/Orders(id)

service.deleteOrder = function (id) {

$http.delete("odata/Orders(" + id + ")")

.success(function (data, status, headers, config) {

service.getOrders();

})

.error(function (data, status, headers, config) { });

};

接下去注脚Controller

//申明Order Controller,注入Order服务

mainModule.controller("orderList", ["$scope", "Order", function ($scope, Order) {

$scope.$on("orders.update", function (event) {

$scope.orders = Order.orders;

})

//增加的order对象

$scope.order = {};

//修改的order对象

$scope.uOrder = {};

//对列表进行查询的对象

$scope.whereOrder = {};

//上一页

$scope.goBefore = function () {

if (Order.page > 1) {

Order.page -= 1;

Order.filter = $scope.getFilterString();

Order.getOrders();

}

}

//下一页

$scope.goNext = function () {

Order.page += 1;

Order.filter = $scope.getFilterString();

Order.getOrders();

}

//得到根据查询条件拿到Order

$scope.getOrders = function () {

Order.filter = $scope.getFilterString();

Order.getOrders();

}

//生成查询条件字符串

$scope.getFilterString = function () {

var filterString = "&$filter=";

var filterArray = [];

if ($scope.whereOrder.No != undefined && $scope.whereOrder.No!="") filterArray.push("No eq '" + $scope.whereOrder.No + "'");

if ($scope.whereOrder.geTotal != undefined && $scope.whereOrder.geTotal.toString() != "") filterArray.push("Total ge " + $scope.whereOrder.geTotal);

if ($scope.whereOrder.leTotal != undefined && $scope.whereOrder.leTotal.toString() != "") filterArray.push("Total le " + $scope.whereOrder.leTotal);

filterString += filterArray.join(" and ");

if (filterString == "&$filter=") filterString = "";

console.log(filterString);

return filterString;

}

//增加Order,调用上面的Order Service

$scope.addOrder = function () {

Order.addOrder($scope.order);

}

//删除order,调用上面的Order Service

$scope.deleteOrder = function (id) {

Order.deleteOrder(id);

}

//修改order

$scope.editOrder = function (order) {

$scope.uOrder = order;

}

//把修改的Order更新到服务器,调用上面的Order Service

$scope.putOrder = function () {

Order.putOrder($scope.uOrder)

}

Order.getOrders();

$scope.page = Order.page;

$scope.orders = Order.orders;

}]);

对应的HTML Templater,由于选择纯HTML写,所以CSS就从未有过了

<body ng-app="MainApp">

<div ng-controller="orderList">

<fieldset>

<legend>List Orders</legend>

<div>

查询条件

No:<input type="text" ng-model="whereOrder.No" />

Total:<input type="number" ng-model="whereOrder.geTotal" />

<input type="number" ng-model="whereOrder.leTotal" />

<input type="button" value="Search" ng-click="getOrders()" />

</div>

<table border="1">

<thead>

<tr>

<th>ID</th>

<th>No</th>

<th>Total</th>

<th>Date</th>

<th colspan="2">Action</th>

</tr>

</thead>

<tbody>

<tr ng-repeat="item in orders">

<td>{{item.Id}}</td>

<td>{{item.No}}</td>

<td>{{item.Total}}</td>

<td>{{item.Date | date : 'yyyy-MM-dd'}}</td>

<td><a href="#nogo" ng-click="editOrder(item)">Edit</a></td>

<td><a href="#nogo" ng-click="deleteOrder(item.Id)">Delete</a></td>

</tr>

</tbody>

</table>

<div>

<input type="button" ng-click="goBefore()" value="上一页" />

<input type="button" ng-disabled="orders.length<3" ng-click="goNext()" value="下一页" />

</div>

</fieldset>

<fieldset>

<legend>Add Order</legend>

<div>

No:<input type="text" ng-model="order.No" /><br />

Total:<input type="number" ng-model="order.Total" /><br />

Date:<input type="date" ng-model="order.Date" /><br />

<input type="button" ng-click="addOrder()" value="Add Order" />

</div>

</fieldset>

<fieldset>

<legend>Update Order</legend>

<div>

<input type="hidden" ng-model="uOrder.Id" />

No:<input type="text" ng-model="uOrder.No" /><br />

Total:<input type="number" ng-model="uOrder.Total" /><br />

Date:<input type="date" ng-model="uOrder.Date" /><br />

<input type="button" ng-click="putOrder()" value="Update Order" />

</div>

</fieldset>

</div>

</body>

下一场运营页面,获得如下效果
爱博体育app手机版 5
增加Order
爱博体育app手机版 6
查询Order
爱博体育app手机版 7
过滤Order
爱博体育app手机版 8
删除ID为1的Order
爱博体育app手机版 9

分页查询
爱博体育app手机版 10

源代码下载
Demo1_20150708214657.rar
引用财富
http://www.asp.net/web-api
Supporting OData Query Options in ASP.NET Web API
2

转发请评释出处
http://giantliu.com/

早先代码

让大家开端吧 !!!

如下图在MSSQL中创制“TblProductList”表。

爱博体育app手机版 11

在ASP.NET MVC 5中开创三个新品类,并基于须要命名并选择Empty项目模板。
在加上文件夹和宗旨援引,勾选MVC和Web API选项:

爱博体育app手机版 12

在那一个项目中运用NuGet软件包管理器安装Entity Framework
6、Jquery和AngularJS。
您还足以从官网下载jquery.js和angular.js,并将其粘贴到品种的“Scripts”文件夹中。

右键单击“Model”文件夹,新建五个ADO.NET 实体数据模型 。
将其命名称为“ProductDataContext.edmx”。

爱博体育app手机版 13

挑选“从数据库生成”,并依赖SQL服务器配置连接字符串。

更改模型后,您将获取TblProductList的实体。

爱博体育app手机版 14

在根目录下创办新文件夹 Interface ,然后再疯长二个类
IProductRepository.cs ,代码如下:

interface IProductRepository
  {
      IEnumerable<TblProductList> GetAll();
      TblProductList Get(int id);
      TblProductList Add(TblProductList item);
      bool Update(TblProductList item);
      bool Delete(int id);
  }

再一次在根目录下新建文件夹 Repositories ,新建类ProductRepository.cs
,以此来促成利用 Entity Framework
举办数据库的始建,读取,更新,删除的操作方法。

public class ProductRepository : IProductRepository
   {
       ProductDBEntities ProductDB = new ProductDBEntities();

       public IEnumerable<TblProductList> GetAll()
       {
           // TO DO : Code to get the list of all the records in database
           return ProductDB.TblProductLists;
       }

       public TblProductList Get(int id)
       {
           // TO DO : Code to find a record in database
           return ProductDB.TblProductLists.Find(id);
       }

       public TblProductList Add(TblProductList item)
       {
           if (item == null)
           {
               throw new ArgumentNullException("item");
           }

           // TO DO : Code to save record into database
           ProductDB.TblProductLists.Add(item);
           ProductDB.SaveChanges();
           return item;
       }

       public bool Update(TblProductList item)
       {
           if (item == null)
           {
               throw new ArgumentNullException("item");
           }

           // TO DO : Code to update record into database
           var products = ProductDB.TblProductLists.Single(a => a.Id == item.Id);
           products.Name = item.Name;
           products.Category = item.Category;
           products.Price = item.Price;
           ProductDB.SaveChanges();

           return true;
       }

       public bool Delete(int id)
       {
           // TO DO : Code to remove the records from database
           TblProductList products = ProductDB.TblProductLists.Find(id);
           ProductDB.TblProductLists.Remove(products);
           ProductDB.SaveChanges();
           return true;
       }
   }

右键单击 Controllers 文件夹并增添新的Web API 2
调控器-空,取名称叫’ProductController.cs’:

public class ProductController : ApiController
   {
       static readonly IProductRepository repository = new ProductRepository();

       public IEnumerable GetAllProducts()
       {
           return repository.GetAll();
       }

       public TblProductList PostProduct(TblProductList item)
       {
           return repository.Add(item);
       }

       public IEnumerable PutProduct(int id, TblProductList product)
       {
           product.Id = id;
           if (repository.Update(product))
           {
               return repository.GetAll();
           }
           else
           {
               return null;
           }
       }

       public bool DeleteProduct(int id)
       {
           if (repository.Delete(id))
           {
               return true;
           }
           else
           {
               return false;
           }
       }
   }

右键单击Controllers文件夹并加多新的调节器,取名字为’HomeController.cs’:

public class HomeController : Controller
   {
       public ActionResult Product()
       {
           return View();
       }
   }

右键单击ActionResult Product(),点击增多视图’Product.cshtml’。

@{
    ViewBag.Title = "Products List";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
@section scripts {

    <link href="~/Content/CustomStyle.css" rel="stylesheet" />
    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script src="~/Scripts/angular.js"></script>
    <script src="~/Scripts/AngularDemo.js"></script>
}
<div ng-app="demoModule" id="body">
    <div ng-controller="demoCtrl">
        <h2>AngularJS CRUD Operations with MVC5 WebAPI</h2>

        <h3>List of Products</h3>

        <table ng-cloak>
            <thead>
                <tr>
                    <th style="display: none;">ID</th>
                    <th>Name</th>
                    <th>Category</th>
                    <th>Price</th>
                    <th>Actions</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="items in productsData">
                    <td hidden="hidden">{{items.Id}}</td>
                    <td>{{items.Name}}</td>
                    <td>{{items.Category}}</td>
                    <td>{{items.Price | currency:'&#8377;':2}}</td>
                    <td>
                   <button ng-model="$scope.Product" 

                   ng-click="edit(productsData[$index])">Edit</button>
                   <button ng-click="delete($index)">Delete</button>
                    </td>
                </tr>
            </tbody>
            <tfoot>
                <tr>
                    <td colspan="6">
                        <hr />
                    </td>
                </tr>
                <tr>
                    <td>Total :</td>
                    <td></td>
                    <td><label ng-bind="total() | 
                    currency:'&#8377;':2"></label></td>
                    <td></td>
                </tr>
            </tfoot>
        </table>
        <br />
        <div style="border-top: solid 2px #282828; width: 430px; height: 10px"> </div>

        <div ng-show="Product.Id != '' ">
            <div>
                <h2>Update Product</h2>
            </div>
            <div hidden="hidden">
                <label for="id">Id</label>
                <input type="text" data-ng-model="Product.Id" />
            </div>
            <div>
                <label for="name">Name</label>
                <input type="text" data-ng-model="Product.Name" />
            </div>

            <div>
                <label for="category">Category</label>
                <input type="text" data-ng-model="Product.Category" />
            </div>

            <div>
                <label for="price">Price</label>
                <input type="text" data-ng-model="Product.Price" />
            </div>
            <br />
            <div>
                <button data-ng-click="update()">Update</button>
                <button data-ng-click="cancel()">Cancel</button>
            </div>
        </div>

        <div ng-hide="Product.Id != '' ">
            <div>
                <h2>Add New Product</h2>
            </div>
            <div>
                <label for="name">Name</label>
                <input type="text" data-ng-model="Product.Name" />
            </div>

            <div>
                <label for="category">Category</label>
                <input type="text" data-ng-model="Product.Category" />
            </div>

            <div>
                <label for="price">Price</label>
                <input type="text" data-ng-model="Product.Price" />
            </div>
            <br />
            <div>
                <button data-ng-click="save()">Save</button>
                <button data-ng-click="clear()">Clear</button>
            </div>
        </div>
    </div>
</div>

Scripts 文件夹中创制二个新的JavaScript文件“Angular
德姆o.js”,以利用角度代码达成CRUD操作。

// Defining angularjs module
var app = angular.module('demoModule', []);

// Defining angularjs Controller and injecting ProductsService
app.controller('demoCtrl', function ($scope, $http, ProductsService) {

    $scope.productsData = null;
    // Fetching records from the factory created at the bottom of the script file
    ProductsService.GetAllRecords().then(function (d) {
        $scope.productsData = d.data; // Success
    }, function () {
        alert('Error Occured !!!'); // Failed
    });

    // Calculate Total of Price After Initialization
    $scope.total = function () {
        var total = 0;
        angular.forEach($scope.productsData, function (item) {
            total += item.Price;
        })
        return total;
    }

    $scope.Product = {
        Id: '',
        Name: '',
        Price: '',
        Category: ''
    };

    // Reset product details
    $scope.clear = function () {
        $scope.Product.Id = '';
        $scope.Product.Name = '';
        $scope.Product.Price = '';
        $scope.Product.Category = '';
    }

    //Add New Item
    $scope.save = function () {
        if ($scope.Product.Name != "" &amp;&amp;
       $scope.Product.Price != "" &amp;&amp; $scope.Product.Category != "") {
            // Call Http request using $.ajax

            //$.ajax({
            //    type: 'POST',
            //    contentType: 'application/json; charset=utf-8',
            //    data: JSON.stringify($scope.Product),
            //    url: 'api/Product/PostProduct',
            //    success: function (data, status) {
            //        $scope.$apply(function () {
            //            $scope.productsData.push(data);
            //            alert("Product Added Successfully !!!");
            //            $scope.clear();
            //        });
            //    },
            //    error: function (status) { }
            //});

            // or you can call Http request using $http
            $http({
                method: 'POST',
                url: 'api/Product/PostProduct/',
                data: $scope.Product
            }).then(function successCallback(response) {
                // this callback will be called asynchronously
                // when the response is available
                $scope.productsData.push(response.data);
                $scope.clear();
                alert("Product Added Successfully !!!");
            }, function errorCallback(response) {
                // called asynchronously if an error occurs
                // or server returns response with an error status.
                alert("Error : " + response.data.ExceptionMessage);
            });
        }
        else {
            alert('Please Enter All the Values !!');
        }
    };

    // Edit product details
    $scope.edit = function (data) {
        $scope.Product = { Id: data.Id, Name: data.Name, Price: data.Price, Category: data.Category };
    }

    // Cancel product details
    $scope.cancel = function () {
        $scope.clear();
    }

    // Update product details
    $scope.update = function () {
        if ($scope.Product.Name != "" &amp;&amp;
       $scope.Product.Price != "" &amp;&amp; $scope.Product.Category != "") {
            $http({
                method: 'PUT',
                url: 'api/Product/PutProduct/' + $scope.Product.Id,
                data: $scope.Product
            }).then(function successCallback(response) {
                $scope.productsData = response.data;
                $scope.clear();
                alert("Product Updated Successfully !!!");
            }, function errorCallback(response) {
                alert("Error : " + response.data.ExceptionMessage);
            });
        }
        else {
            alert('Please Enter All the Values !!');
        }
    };

    // Delete product details
    $scope.delete = function (index) {
        $http({
            method: 'DELETE',
            url: 'api/Product/DeleteProduct/' + $scope.productsData[index].Id,
        }).then(function successCallback(response) {
            $scope.productsData.splice(index, 1);
            alert("Product Deleted Successfully !!!");
        }, function errorCallback(response) {
            alert("Error : " + response.data.ExceptionMessage);
        });
    };

});

// Here I have created a factory which is a popular way to create and configure services.
// You may also create the factories in another script file which is best practice.

app.factory('ProductsService', function ($http) {
    var fac = {};
    fac.GetAllRecords = function () {
        return $http.get('api/Product/GetAllProducts');
    }
    return fac;
});

注意

你能够使用jQuery中的$.ajax或来自angular.js的$http来进行HTTP请求。

可是最棒正是选取angular.js的$http,因为使用$.ajax
会迫使大家利用$scope.apply,假若你使用$ http无需。

你也能够选择
$resource
,那被以为是在RESTful Web API中开始展览CRUD操作的最好做法。
本教程适用于初学者,所以作者企图通过使用$http 来保持轻巧。

依据架构的关联,实际不是调控器,您能够在大家的自定义务工作厂中调用$http央求POST,PUT,DELETE,就疑似自家曾经为$http.get()所做的那样,以便我们的调节器看起来很干净,并表现出适当的关怀点分离。

译者注:(关切点分离(Separation of
concerns,SOC)是对只与“特定概念、目的”(关心点)相关联的软件组成都部队分实行“标志、封装和垄断(monopoly)”的力量,即标记、封装和垄断(monopoly)关注点的力量。是管理犬牙相错的多少个条件。由于关切点混杂在共同会导致复杂性大大扩展,所以能够把分歧的关怀点分离开来,分别管理就是拍卖复杂的二个尺码,一种形式。)

近日,增加一个布局视图: ‘_Layout.cshtml’。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <meta name="viewport" content="width=device-width" />
</head>
<body>
    <div id="body">
        @RenderSection("featured", required: false)
        <section class="content-wrapper main-content clear-fix">
            @RenderBody()
        </section>
    </div>

    @RenderSection("scripts", required: false)
</body>
</html>

充实样式表’CustomStyle.css’以改正页面包车型大巴外观和美感。

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
    display: none !important;
}

body {
            margin: 20px;
            font-family: "Arial", "Helventica", sans-serif;
        }

        label {
            width: 80px;
            display: inline-block;
        }

        button {
            display: inline-block;
            outline: none;
            cursor: pointer;
            text-align: center;
            text-decoration: none;
            padding: .4em 1.1em .4em;
            color: #fef4e9;
            border: solid 1px #006fb9;
            background: #1276bb;
        }

            button:hover {
                text-decoration: none;
                background: #282828;
                border: solid 1px #000;
            }

        table {
            padding-top: 1em;
        }

        thead, tfoot {
            font-weight: 600;
        }

        th, td {
            padding: .1em .5em;
            text-align: left;
        }

            td li, td ul {
                margin: 0;
                padding: 0;
            }

            td li {
                display: inline;
            }

                td li::after {
                    content: ',';
                }

                td li:last-child::after {
                    content: '';
                }

注意

在那边,小编早就依据
AngularJS文档
定义了在我们的“Product.cshtml”中选拔的ng-cloak指令的体制。<br
class=”Apple-interchange-newline”><div
id=”inner-editor”></div>

ngCloak指令用于幸免在加载应用程序时浏览器以原始(未编写翻译)情势简单彰显Angular
HTML模板。 使用此指令可防止HTML模板展现引起的不期待的闪光效应。

相关文章