国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

Asp.Net Web API 2第十八課——Working with Entity Relations in OData

2019-11-15 02:30:53
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

asp.net Web API 2第十八課——Working with Entity Relations in OData

前言

  閱讀本文之前,您也可以到Asp.Net Web API 2 系列導(dǎo)航進(jìn)行查看http://www.survivalescaperooms.com/aehyok/p/3446289.html。 

  本文的示例代碼的下載地址為http://pan.baidu.com/s/1o6lqXN8

大多數(shù)的數(shù)據(jù)集定義實(shí)體間的關(guān)系:客戶(hù)有訂單、書(shū)籍有作者、產(chǎn)品有供應(yīng)商。客戶(hù)端可以使用OData操作實(shí)體間的關(guān)系。給定一個(gè)產(chǎn)品,你可以找到該產(chǎn)品的供應(yīng)商。您也可以創(chuàng)建或者刪除關(guān)系。例如,您也可以為一個(gè)產(chǎn)品設(shè)置一個(gè)供應(yīng)商。

  本教程將會(huì)展示在A(yíng)sp.Net Web API中支持這些操作。本文的教程是建立在上一節(jié)的教程之上http://www.survivalescaperooms.com/aehyok/p/3545824.html。

Add a Supplier Entity添加一個(gè)供應(yīng)商實(shí)體類(lèi)

首先我們需要來(lái)添加一個(gè)Supplier的實(shí)體類(lèi)

namespace OData.Models{    public class Supplier    {        [Key]        public string Key { get; set; }        public string Name { get; set; }    }}

這個(gè)類(lèi)使用了一個(gè)字符串類(lèi)型的實(shí)體鍵。在實(shí)踐中,這可能比使用整形鍵不太常見(jiàn)的。但它是值得的看到OData如何處理除了整數(shù)以外的其他鍵類(lèi)型。

接下來(lái),我們將通過(guò)在PRoduct類(lèi)上添加一個(gè)Supplier的屬性來(lái)建立一個(gè)關(guān)系。

    public class Product    {        public int ID { get; set; }        public string Name { get; set; }        public decimal Price { get; set; }        public string Category { get; set; }        // New code        [ForeignKey("Supplier")]        public string SupplierId { get; set; }        public virtual Supplier Supplier { get; set; }    }

添加一個(gè)新的DbSetProductServiceContext類(lèi),從而使實(shí)體框架將包括Supplier數(shù)據(jù)庫(kù)表中。

    public class ProductServiceContext : DbContext    {        public ProductServiceContext() : base("name=ProductServiceContext")        {        }        public DbSet<Product> Products { get; set; }        ///New Code        public DbSet<Supplier> Suppliers { get; set; }        }

在WebApiConfig.cs,添加一個(gè)“Suppliers”實(shí)體的EDM模型:

            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();            builder.EntitySet<Product>("Products");            // New code:            builder.EntitySet<Supplier>("Suppliers");

Navigation Properties導(dǎo)航屬性

為了得到一個(gè)產(chǎn)品的供應(yīng)商,客戶(hù)端發(fā)送了一個(gè)Get請(qǐng)求:

GET /Products(1)/Supplier

在Product類(lèi)型上有一個(gè)Supplier的導(dǎo)航屬性。在這個(gè)實(shí)例中,Supplier是一個(gè)單一的項(xiàng)。但是一個(gè)導(dǎo)航屬性也能返回一個(gè)集合(一對(duì)多或者多對(duì)多的 關(guān)系)。

為了支持這個(gè)請(qǐng)求,在ProductsController上添加如下方法:

        // GET /Products(1)/Supplier        public Supplier GetSupplier([FromODataUri] int key)        {            Product product = db.Products.FirstOrDefault(p => p.ID == key);            if (product == null)            {                throw new HttpResponseException(HttpStatusCode.NotFound);            }            return product.Supplier;        }

key這個(gè)參數(shù)就是這個(gè)Product的鍵。這個(gè)方法返回關(guān)聯(lián)的實(shí)體——在這個(gè)實(shí)例中,就是一個(gè)Supplier對(duì)象。方法的名稱(chēng)和參數(shù)的名稱(chēng)都是非常重要的。總之,如果導(dǎo)航屬性被命名為一個(gè)“X”,你需要添加一個(gè)被命名為“GetX”的方法。這個(gè)方法必須采用一個(gè)命名為“key”的參數(shù),用來(lái)匹配父類(lèi)數(shù)據(jù)類(lèi)型的key。

它也是很重要的在鍵參數(shù)上擁有【FromOdataUri】的屬性。當(dāng)它從請(qǐng)求的URL中解析鍵時(shí),這個(gè)屬性將會(huì)告訴Web API去使用Odata語(yǔ)法規(guī)則。

Creating and Deleting Links

OData支持創(chuàng)建和刪除兩個(gè)實(shí)體之間的關(guān)系。在OData術(shù)語(yǔ)中,這個(gè)關(guān)系就是一個(gè)“link”。每個(gè)link有一個(gè)攜帶entity/$links/entity的Url。例如,由產(chǎn)品到供應(yīng)商的鏈接看起來(lái)像這樣:

/Products(1)/$links/Supplier

為了創(chuàng)建一個(gè)新的鏈接,這個(gè)客戶(hù)端發(fā)送了一個(gè)post請(qǐng)求到這個(gè)鏈接URI。請(qǐng)求的消息體就是目標(biāo)實(shí)體的URI。例如,假設(shè)有一個(gè)供應(yīng)商的鍵為“CTSO”。為了創(chuàng)建一個(gè)鏈接由“Product(1)”到”Supplier('CTSO')“,客戶(hù)端發(fā)送一個(gè)請(qǐng)求如下:

POST http://localhost/odata/Products(1)/$links/SupplierContent-Type: application/jsonContent-Length: 50{"url":"http://localhost/odata/Suppliers('CTSO')"}

對(duì)于刪除一個(gè)鏈接,客戶(hù)端發(fā)送了一個(gè)DELETE 請(qǐng)求到鏈接URI。

Creating Links

為啟用一個(gè)客戶(hù)端去創(chuàng)建產(chǎn)品-供應(yīng)商的鏈接,需要在ProductsController類(lèi)中添加如下的代碼:

[AcceptVerbs("POST", "PUT")]public async Task<IHttpActionResult> CreateLink([FromODataUri] int key, string navigationProperty, [FromBody] Uri link){    if (!ModelState.IsValid)    {        return BadRequest(ModelState);    }                Product product = await db.Products.FindAsync(key);    if (product == null)    {        return NotFound();    }                switch (navigationProperty)    {        case "Supplier":            string supplierKey = GetKeyFromLinkUri<string>(link);            Supplier supplier = await db.Suppliers.FindAsync(supplierKey);            if (supplier == null)            {                return NotFound();            }            product.Supplier = supplier;            await db.SaveChangesAsync();            return StatusCode(HttpStatusCode.NoContent);        default:            return NotFound();    }}

這個(gè)方法有三個(gè)參數(shù):

第一個(gè)key:就是引導(dǎo)到父類(lèi)實(shí)體的鍵

第二個(gè)navigationProperty: 導(dǎo)航屬性的名稱(chēng)。例如,最合適的導(dǎo)航屬性Supplier。

第三個(gè)link:被鏈接實(shí)體的OData的URI。這個(gè)值是從消息體中獲得。例如,這個(gè)鏈接URI可能是”http://localhost/odata/Suppliers('CTSO')“,也就是供應(yīng)商中有ID="CTSO"。

這個(gè)方法用這個(gè)鏈接去查找Supplier。如果匹配的供應(yīng)商被發(fā)現(xiàn),這個(gè)方法將會(huì)設(shè)置Product實(shí)體類(lèi)的Supplier的屬性,并且保存結(jié)果到數(shù)據(jù)庫(kù)。

其中最難的部分是解析鏈接URI。從根本上來(lái)說(shuō),你需要模擬發(fā)送一個(gè)get請(qǐng)求到那個(gè)URI。接下來(lái)的輔助方法將會(huì)展示如何處理它。這個(gè)方法調(diào)用Web API路由過(guò)程,返回一個(gè)OData實(shí)體,展現(xiàn)被轉(zhuǎn)換的OData路徑。對(duì)于一個(gè)鏈接URI,這個(gè)片段數(shù)中應(yīng)該有一個(gè)實(shí)體鍵。

// Helper method to extract the key from an OData link URI.private TKey GetKeyFromLinkUri<TKey>(Uri link){    TKey key = default(TKey);    // Get the route that was used for this request.    IHttpRoute route = Request.GetRouteData().Route;    // Create an equivalent self-hosted route.     IHttpRoute newRoute = new HttpRoute(route.RouteTemplate,         new HttpRouteValueDictionary(route.Defaults),         new HttpRouteValueDictionary(route.Constraints),        new HttpRouteValueDictionary(route.DataTokens), route.Handler);    // Create a fake GET request for the link URI.    var tmpRequest = new HttpRequestMessage(HttpMethod.Get, link);    // Send this request through the routing process.    var routeData = newRoute.GetRouteData(        Request.GetConfiguration().VirtualPathRoot, tmpRequest);    // If the GET request matches the route, use the path segments to find the key.    if (routeData != null)    {        ODataPath path = tmpRequest.GetODataPath();        var segment = path.Segments.OfType<KeyValuePathSegment>().FirstOrDefault();        if (segment != null)        {            // Convert the segment into the key type.            key = (TKey)ODataUriUtils.ConvertFromUriLiteral(                segment.Value, ODataVersion.V3);        }    }    return key;}

Deleting Links

對(duì)于刪除一個(gè)鏈接,在ProductsController類(lèi)中添加如下代碼:

public async Task<IHttpActionResult> DeleteLink([FromODataUri] int key, string navigationProperty){    Product product = await db.Products.FindAsync(key);    if (product == null)    {        return NotFound();    }    switch (navigationProperty)    {        case "Supplier":            product.Supplier = null;            await db.SaveChangesAsync();            return StatusCode(HttpStatusCode.NoContent);        default:            return NotFound();    }}

在這個(gè)例子中,這個(gè)導(dǎo)航屬性是一個(gè)簡(jiǎn)單的Supplier實(shí)體。如果導(dǎo)航屬性是一個(gè)集合,對(duì)于刪除一個(gè)鏈接的URI必須在被關(guān)聯(lián)的實(shí)體中有一個(gè)鍵。例如:

DELETE /odata/Customers(1)/$links/Orders(1)

這里展示的則是1對(duì)多的關(guān)系中,刪除其中的一個(gè)的例子。

這個(gè)請(qǐng)求就是從客戶(hù)1中移除訂單為1的。這個(gè)DeleteLink方法將會(huì)有如下簽名:

void DeleteLink([FromODataUri] int key, string relatedKey, string navigationProperty);

簡(jiǎn)單測(cè)試結(jié)果

1、http://localhost:3629/Odata/Products(1)/Supplier

2、

將ID=2的Supplier修改為WING

請(qǐng)求Header

POST http://localhost/odata/Products(2)/$links/SupplierContent-Type: application/jsonContent-Length: 50

請(qǐng)求Body

{"url":"http://localhost/odata/Suppliers('WING')"}

現(xiàn)在再次查看http://localhost/Odata/Products

3、DELETE http://localhost/odata/Products(2)/$links/Supplier那么這樣就可以將上面的SupplierId=WING修改為null

然后再次執(zhí)行http://localhost/Odata/Products查看

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 耿马| 望谟县| 息烽县| 曲阜市| 筠连县| 涡阳县| 甘洛县| 小金县| 湄潭县| 青铜峡市| 泰顺县| 突泉县| 白玉县| 海伦市| 区。| 兴安盟| 达孜县| 乌兰察布市| 保康县| 秦皇岛市| 波密县| 旬邑县| 东辽县| 兖州市| 新乡市| 深圳市| 海南省| 建阳市| 泰来县| 南郑县| 长岛县| 尖扎县| 民权县| 巴林左旗| 宝兴县| 苏尼特左旗| 雷州市| 明水县| 吉水县| 南平市| 高碑店市|