Entity Framework 6 Recipes 2nd Edition (9-1) update separately separated entities with Web API

Source: Internet
Author: User
Tags connectionstrings

Nineth. Using EF in an N-tier architecture application

Not all applications can be completely written to a single process (that is, reside in a single physical layer), in fact, in today's evolving network world, a large number of application structures contain classic presentation layers, applications, and data layers, and they may spread across multiple computers, The logical layer of a domain that is distributed to an application on a separate computer does not involve much of the proxy server encoding, serialization, and network protocols, and applications can span many devices, from small to a mobile device to a data server that contains information about all of the enterprise's accounts.

Fortunately, EF can be used in multi-layered frameworks such as the Wcf,web API.

In this chapter, we will try to cover the use of multi-tier applications in EF, where n-tier refers to the application's presentation layer, the business logic layer, and the data layer, respectively, on different servers. This physically independent distribution contributes to scalability, maintainability, and late extensibility of the program, but it can have a performance impact when a process needs to cross the computer. The N-tier architecture poses additional challenges to EF's state tracking. First, EF's contextobject fetch data is destroyed after it is sent to the client, and data modifications on the client are not tracked.

Before updating, a context object must be created based on the data submitted, and it is clear that the new object does not know the existence of the previous object, including the original value of the entity. In this chapter, we'll look at the tool approach to dealing with this tracking challenge.

In previous versions of EF, a developer could use the tracking entities template to help us keep track of the entities that were separated. Then in EF6, it has been deprecated, but the legacy ObjectContext will support tracking entities, and this chapter will focus on Basic N-tier creation, read, update, and delete operations. In addition, you will delve into the way entities and agents are serialized, concurrency, and entity tracking.

9-1. Updating separate entities with the Web API

Problem

You want to use rest-based Web services to insert, delete, and update to the data storage tier. In addition, you want to implement the management of data access through the EF6 code first method. In this example, we emulate an n-tier scenario where a client invocation of a console application exposes a restful service-based Web API application. Each tier uses a separate VS solution, which is more conducive to emulating N-tier configuration and debugging.

Solution Solutions

Suppose there is a model like the one shown in Fig. 9-1

Figure 9-1. an order model

Our model represents the order. We want to put the model and database code behind a Web API service so that any customer can insert, update, and delete order data over HTTP. In order to create this service, do the following:

1. Create a new ASP. NET MVC 4 Web application project named "Recipe1.service" and select the Web API template in the wizard ...

2. Add a new "controller" to the project, named "Ordercontroller".

3. Add the Order class, as shown in the code listing 9-1:

Listing 9-1. Order Entity Class

public class Order

{

public int OrderId {get; set;}

public string Product {get; set;}

public int Quantity {get; set;}

public string Status {get; set;}

Public byte[] TimeStamp {get; set;}

}

4. Add a reference to the EF6 in the "Recipe1.service" project. It's best to add it with the NuGet package Manager. Right-click on references and select Manage NuGet packages. From the Online tab, locate and install the EF6 package. This will download, install and configure the EF6 library into your project.

5. Then add a new Class "Recipe1context", type the code such as listing 9-2, and make sure that the class inherits from EF6 DbContext

297

Listing 9-2. Context Class

public class Recipe1context:dbcontext

{

Public Recipe1context (): Base ("Recipe1connectionstring") {}

Public dbset<order> Orders {get; set;}

protected override void Onmodelcreating (Dbmodelbuilder modelBuilder)

{

Modelbuilder.entity<order> (). ToTable ("Chapter9.order");

Following configuration enables timestamp to be concurrency token

Modelbuilder.entity<order> (). Property (x = X.timestamp)

. Isconcurrencytoken ()

. Hasdatabasegeneratedoption (databasegeneratedoption.computed);

}

}

6. Insert the configuration of the connection database in the connectionstrings section of Web.configk, such as listing 9-3:

Listing 9-3. Connection String for the Recipe1 Web API Service

<connectionStrings>

<add name= "Recipe1connectionstring"

Connectionstring= "Data source=.;

Initial catalog=efrecipes;

Integrated security=true;

Multipleactiveresultsets=true "

Providername= "System.Data.SqlClient"/>

</connectionStrings>

7. Insert the code shown in listing 9-4 into the Application_Start method of Global.asax

Listing 9-4. Disable the Entity Framework Model compatibility Check

protected void Application_Start ()

{

Disable Entity Framework Model compatibilty

Database.setinitializer<recipe1context> (NULL);

...

}

8. Finally, replace the code in Ordercontroller with the code shown in Listing 9-5.

Listing 9-5. Code for the Ordercontroller

public class Ordercontroller:apicontroller

{

GET Api/order

Public ienumerable<order> Get ()

{

using (var context = new Recipe1context ())

{

Return to context. Orders.tolist ();

}

}

GET API/ORDER/5

Public Order Get (int id)

{

using (var context = new Recipe1context ())

{

Return to context. Orders.firstordefault (x = X.orderid = = ID);

}

}

POST Api/order

Public Httpresponsemessage Post (order order)

{

Cleanup data from previous requests

Cleanup ();

using (var context = new Recipe1context ())

{

Context. Orders.add (order);

Context. SaveChanges ();

Create httpresponsemessage to wrap result, assigning Http Status code of 201,

Which informs client that resource created successfully

var response = Request.createresponse (httpstatuscode.created, order);

Add location of newly-created resource to response header

Response. Headers.location = new Uri (Url.link ("Defaultapi",

New {id = order. ORDERID}));

return response;

}

}

PUT API/ORDER/5

Public Httpresponsemessage Put (order order)

{

using (var context = new Recipe1context ())

{

Context. Entry (Order). state = entitystate.modified;

Context. SaveChanges ();

Return Http Status code of informing client that Resouce updated successfully

Return Request.createresponse (Httpstatuscode.ok, order);

}

}

DELETE API/ORDER/5

Public httpresponsemessage Delete (int id)

{

using (var context = new Recipe1context ())

{

var order = context. Orders.firstordefault (x = X.orderid = = ID);

Context. Orders.remove (order);

Context. SaveChanges ();

Return Http Status Code of informing client that Resouce removed successfully

Return Request.createresponse (Httpstatuscode.ok);

}

}

private void Cleanup ()

{

using (var context = new Recipe1context ())

{

Context. Database.executesqlcommand ("Delete from chapter9.[ Order] ");

}

}

}

It should be stressed that we can use a large number of tools (such as code generation template) to generate a working controller to save the above changes.

Next, create a client that invokes the above Web API service.

9. Create a new solution that contains the console application named "Recipe1.client".

10. Add the same order entity class as listing 9-1

Finally, replace the code in the Program.cs with the code in Listing 9-6

Listing 9-6. Our Windows Console application, serves as our Test Client

Private HttpClient _client;

Private Order _order;

private static void Main ()

{

Task t = Run ();

T.wait ();

Console.WriteLine ("\npress <enter> to continue ...");

Console.ReadLine ();

}

private static Async Task Run ()

{

Create instance of the program class

var program = new program ();

Program. Servicesetup ();

Program. Createorder ();

Proceed until order is added

Await program. Postorderasync ();

Program. Changeorder ();

Proceed until order is changed

Await program. Putorderasync ();

Proceed until order is removed

Await program. Removeorderasync ();

}

private void Servicesetup ()

{

Specifies the URL of the calling Web API

_client = new HttpClient {baseaddress = new Uri ("http://localhost:3237/")};

Accept the requested header content

Returning resources in JSON format

_client. DEFAULTREQUESTHEADERS.ACCEPT.ADD (New Mediatypewithqualityheadervalue ("Application/json"));

}

private void Createorder ()

{

Create a New Order

_order = New Order {Product = "Camping Tent", Quantity = 3, Status = "Received"};

}

Private async Task Postorderasync ()

{

Invoking the service with the Web API client API

var response = await _client. Postasjsonasync ("Api/order", _order);

Uri Neworderuri;

if (response. Issuccessstatuscode)

{

To capture a URI for a new resource

Neworderuri = Response. Headers.location;

Gets the order that contains the database self-increment ID returned from the server

_order = await response. Content.readasasync<order> ();

Console.WriteLine ("Successfully created order. Here is the URL to new resource: {0} ", Neworderuri);

}

Else

Console.WriteLine ("{0} ({1})", (int) response. StatusCode, Response. Reasonphrase);

}

private void Changeorder ()

{

Update Order

_order. Quantity = 10;

}

Private async Task Putorderasync ()

{

Construct Httpput call the appropriate put method in the Web API service

var response = await _client. Putasjsonasync ("Api/order", _order);

if (response. Issuccessstatuscode)

{

Gets the order that contains the new quanity after the update returned from the server

_order = await response. Content.readasasync<order> ();

Console.WriteLine ("Successfully updated Order: {0}", Response. StatusCode);

}

Else

Console.WriteLine ("{0} ({1})", (int) response. StatusCode, Response. Reasonphrase);

}

Private async Task Removeorderasync ()

{

Remove order

var uri = "api/order/" + _order. OrderId;

var response = await _client. Deleteasync (URI);

if (response. Issuccessstatuscode)

Console.WriteLine ("sucessfully deleted order: {0}", Response. StatusCode);

Else

Console.WriteLine ("{0} ({1})", (int) response. StatusCode, Response. Reasonphrase);

}

Client output results such as Listing 9-6:

==========================================================================

Successfully created Order:here is URL to new resource:http://localhost:3237/api/order/1054

Successfully updated Order:ok

sucessfully deleted Order:ok

==========================================================================

How does it work?

Looking at the client side, we perform the next operation, change the quantity of the order, and send the new order to the Web API using the Putasjsonasync method of the HttpClient object. If the Web API service's Web API controller put The Action method adds a breakpoint and you can see that the method parameter receives an order object. The entry method that calls the context object passes a reference to the order entity, and then sets the state to Modified. A subsequent call to SaveChanges produces an SQL UPDATE statement. All columns of the order are updated. In this section, we see how to update only the properties that you want to update. and returned to the caller one for the HTTP status code. Looking at the client again, we finally call the remove operation, which will remove the state from the database. We do this by attaching the ID of the order to the URI and calling the Deleteasync of the Web API. On the server side, we get the target order from the database and pass the Remove method to the context object of the order, so that the order status is set to deleted.

A subsequent call to SaveChanges produces a SQL DELETE statement and deletes the order from the database. In this section, after we encapsulate the EF data operation in the Web API service, the client may invoke the service through the HttpClient object, publish it through the HTTP method of the Web API, add a new record with the Post action method, and update a record with the Put action method. And the Delete action method to delete a record. At the same time we learned the EF6 code first method, of course, in practical applications, we may prefer to create a separate layer (VS's Class Library project), the EF6 database access code from the Web API service to separate out.

Entity Framework 6 Recipes 2nd Edition (9-1) update separately separated entities with Web API

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.