Objective
Before reading this article, you can also view the http://www.cnblogs.com/aehyok/p/3446289.html in the ASP. NET Web API 2 series navigation.
The sample code for this article is http://pan.baidu.com/s/1o6lqXN8
Most datasets define relationships between entities: Customers have orders, books have authors, and products have suppliers. Clients can use OData to manipulate relationships between entities. Given a product, you can find the supplier of the product. You can also create or delete relationships. For example, you can also set up a vendor for a product.
This tutorial will show you the support for these operations in the ASP. The tutorial in this article is based on the previous section of the tutorial http://www.cnblogs.com/aehyok/p/3545824.html.
Add a Supplier entity adds a vendor entities class
First we need to add a supplier entity class
namespace odata.models{public class Supplier { [Key] public string Key {get; set;} public string Name {get; set;}} }
This class uses an entity key of type String. In practice, this may be less common than using reshape keys. But it is worth seeing how OData handles other key types in addition to integers.
Next, we will establish a relationship by adding a supplier property on the Product class.
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;} }
Add a new DbSet to the class so that the ProductServiceContext Entity Framework will include supplier in the database table.
public class Productservicecontext:dbcontext {public productservicecontext (): Base ("Name= Productservicecontext ") { } public dbset<product> products {get; set;} New Code public dbset<supplier> Suppliers {get; set;} }
In WebApiConfig.cs, add an EDM model for the "Suppliers" entity:
Odataconventionmodelbuilder builder = new Odataconventionmodelbuilder (); Builder. Entityset<product> ("Products"); New code: Builder. Entityset<supplier> ("Suppliers");
Navigation Properties Navigation Property
To get a vendor for a product, the client sends a GET request:
Get/products (1)/supplier
There is a supplier navigation property on the product type. In this instance, supplier is a single item. But a navigation property can also return a collection (one-to-many or many-to-many relationships).
To support this request, add the following method on the 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 This parameter is the key for this product. This method returns the associated entity-in this instance, a supplier object. The name of the method and the name of the parameter are very important. In summary, if the navigation property is named an "X", you need to add a method named "GetX". This method must take a parameter named "key" to match the key of the parent data type.
It is also important to have the attribute "Fromodatauri" on the key parameter. When it resolves a key from the requested URL, this property tells the Web API to use the OData syntax rules.
Creating and Deleting Links
OData supports the creation and deletion of relationships between two entities. In the OData terminology, this relationship is a "link". Each link has a URL that carries an entity/$links/entity . For example, a link from the product to the vendor looks like this:
/products (1)/$links/supplier
In order to create a new link, this client sends a POST request to this link URI. The message body of the request is the URI of the target entity. For example, suppose you have a vendor with a key of "Ctso". In order to create a link by "Product (1)" to "Supplier (' Ctso ')", the client sends a request as follows:
POST http://localhost/odata/Products (1)/$links/suppliercontent-type:application/jsoncontent-length:50
{"url": "Http://localhost/odata/Suppliers (' Ctso ')"}
For deleting a link, the client sends a DELETE request to the link URI.
Creating Links
To enable a client to create a product-vendor link, you need to add the following code to the ProductsController class:
[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 (); }}
This method has three parameters:
First key: Is the key that is booted to the parent class entity
Second NavigationProperty: The name of the navigation property. For example, the most appropriate navigation property is supplier.
Third link: The URI of the OData of the linked entity. This value is obtained from the body of the message. For example, the link URI might be "http://localhost/odata/Suppliers (' Ctso ')", which is the id= "Ctso" in the vendor.
This method uses this link to find the supplier. If a matching vendor is found, this method sets the Supplier property of the Product entity class and saves the result to the database.
The hardest part is parsing the link URI. Fundamentally, you need to simulate sending a GET request to that URI. The next helper method will show you how to handle it. This method invokes the Web API routing process and returns an OData entity that represents the transformed OData path. For a link URI, there should be an entity key in the number of fragments.
Helper method to extract the key from an OData link uri.private TKey getkeyfromlinkuri<tkey> (URI link) {TKey k EY = Default (TKey); Get the route that is 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
For deleting a link, add the following code to the ProductsController class:
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 (); }}
In this example, this navigation property is a simple supplier entity. If the navigation property is a collection, the URI for deleting a link must have a key in the entity being associated. For example:
Delete/odata/customers (1)/$links/orders (1)
Here is the example of a 1-to-many relationship that removes one of them.
This request removes the order 1 from customer 1. This deletelink method will have the following signature:
void Deletelink ([fromodatauri] int key, String relatedkey, string navigationproperty);
Simple test Results
1, http://localhost:3629/Odata/Products (1)/supplier
2.
Change id=2 's supplier to wing
Request Header
POST http://localhost/odata/Products (2)/$links/suppliercontent-type:application/jsoncontent-length:50
Request Body
{"url": "Http://localhost/odata/Suppliers (' WING ')"}
Now look again at http://localhost/Odata/Products
3, DELETE http://localhost/odata/Products (2)/$links/supplier so you can change the above supplierid=wing to null
Then perform http://localhost/Odata/Products view again
Summarize
The reference link for this article is http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/working-with-entity-relations
The sample code for this article is http://pan.baidu.com/s/1o6lqXN8
ASP. 2 18th Lesson--working with Entity relations in OData