When working with Entity Framework entities, most of the time we operate on entity model entities, a combination of database manipulation contexts that can be easily implemented using a variety of convenient means, such as LINQ, and everything looks good. However, if you consider using WCF, you may encounter a number of related traps or errors. Because the object of the entity model entity may include references to other entities, it is not possible to serialize in WCF, errors occur, and WCF-based may not be able to make efficient use of express expressions, and problems such as the inability to use LINQ directly can be seen in a brain. Based on the above problems, this paper expounds the solution of my whole Entity Framework, and introduces the data transmission model DTO to solve the problem, this paper mainly introduces the separation and union of the data transmission model DTO and entity model entities, so as to realize our unobstructed and An efficient WCF application framework.
1. Entity model entities cannot be serialized in WCF
For example, the entity Framework entities class that we define contains references to other objects, such as a role object that has an association with other tables, using the traditional way of adding [DataContract] to the entity class by default.
/// <summary> ///role/// </summary>[DataContract (isreference =true)] Public classRole {/// <summary> ///default constructor (requires initialization of properties for this processing)/// </summary> PublicRole () { This. id=System.Guid.NewGuid (). ToString (); //children = new hashset<role> (); //Users = new hashset<user> (); } #regionProperty Members[DataMember] Public Virtual stringID {Get;Set; } /// <summary> ///Role Name/// </summary>[DataMember] Public Virtual stringName {Get;Set; } /// <summary> ///Parent ID/// </summary>[DataMember] Public Virtual stringParentID {Get;Set; } [DataMember] Public VirtualIcollection<role> Children {Get;Set; } [DataMember] Public VirtualRole Parent {Get;Set; } [DataMember] Public VirtualIcollection<user> Users {Get;Set; } #endregion }
The code used in the WCF service interface is shown below.
Public class Service1:iservice1 { public list<role> getallroles () { return ifactory.instance <IRoleBLL>(). GetAll (). ToList (); } .........
So when we use it in WCF, we get the following hint.
An error occurred while receiving an HTTP response to Http://localhost:11229/Service1.svc. This may be due to the fact that the service endpoint bindings are not using the HTTP protocol. This may also be caused by the server aborting the HTTP request context (possibly due to a service shutdown). For more information, see Server logs.
By default, the Entity framework, in order to support some of its advanced features (lazy loading, etc.), will automatically generate a proxy class that is set to true. If we need to disable the automatic generation of proxy classes, you can do processing settings inside the database operation context DbContext.
false;
If set to False, the WCF service works fine, but the collection of other objects inside the entity class object is empty-that is, WCF cannot return the contents of those references.
At the same time, in the Entity Framework framework, this kind of entity class through the layers, is also a deprecated practice, because the data transmitted in WCF is serial number of data, and can not be used as a local LINQ to implement data processing operations.
So how do we build Entity Framework entities based on the WCF reference?
2. Introduction of DTO for data transmission object
The disadvantages of using Entity Framework entities class objects directly are described earlier, and if you use this entity class all the way, many object references are empty, which is inconvenient to us at the interface layer, and may also cause some related problems in the WCF framework.
We have introduced a DTO (data transfer object) based on the above problem.
A data Transfer object (DTO) is a Poco object that has no behavior, and is intended only to encapsulate the domain object, implement data transfer between layers and layer, and interact with data transfer objects (DTOS) between the interface presentation layer and the application layer. Data transfer objects The DTO itself is not a business object, and the data transfer object is designed according to the needs of the UI.
This object and the entity class of the concrete data store are independent, it can be said that the entity class is a mapping body, the name can be different from the entity class, the number of attributes can also be inconsistent with the entity class. Since the introduction of another Dto object layer outside the entity object layer, then the mutual conversion is certainly not inevitable, we to avoid the manual mapping method, introduced another powerful automation mapping tool AutoMapper, to help us to quickly, efficiently and intelligently implement two layers of object mapping processing.
The use of AutoMapper is relatively simple, generally if the object properties have been, they will implement the automatic mapping of properties, as shown below.
Mapper.createmap<roleinfo, role> ();
If the property names of the two are inconsistent, you can specify them by Formember, similar to the code below.
Automapper.mapper.createmap<blogentry, blogpostdto>() = Dto. PostID, opt = opt. Mapfrom (entity = entity.id));
AutoMapper can also write the mapping information into a class, and then load it uniformly.
Mapper.initialize (cfg = { cfg). Addprofile<OrganizationProfile>();});
so based on the diagram pattern above, because we have the DTO and entity generated automatically by the Code generation tool, their attribute names are consistent, Then we just need to map the objects to each other at the application layer.
public class RoleService: Baselocalservice<roleinfo, Role> private irolebll BLL = null public RoleService (): base ( Ifactory.instance<irolebll> ()) {BLL = basebll as IROLEBLL; // dto and the entity model are mapped to each other Mapper.cre Atemap<roleinfo, Role> (); Mapper.createmap <role, Roleinfo> (); } }
Based on the mapping of this internal docking, we can provide a uniform DTO object service at the facade interface layer, while the business logic layer (that is, the processing of the Entity Framework) is still passed using its entity object. Below I provide several encapsulated base class interfaces for understanding the interface between DTOs and entity.
1) Pass in the Dto object and convert it to an entity object, using an EF object to insert.
/// <summary> ///inserts the specified object into the database/// </summary> /// <param name= "DTO" >the specified object</param> /// <returns>Execution Successful return<c>true</c>, otherwise the<c>false</c></returns> Public Virtual BOOLInsert (dto dto) {Entity T= Dto. Mapto<entity>(); returnBasebll.insert (t); }
2) Gets the entity object from the EF framework based on the criteria and returns the Dto object after conversion
/// <summary> ///querying the database, returning the object with the specified ID/// </summary> /// <param name= "id" >the value of the ID primary key</param> /// <returns>The specified object is returned if it exists, otherwise null is returned</returns> Public VirtualDTO FindByID (Objectid) {Entity t=Basebll.findbyid (ID); returnT.mapto<dto>(); }
3) Obtain the Entity collection object from the EF framework based on the criteria and convert it to a DTO list object
/// <summary> /// returns a collection of all objects in the database /// </summary> /// <returns></returns> Public Virtual Icollection<dto> GetAll () { ICollection<Entity> tList = basebll.getall (); return tlist.maptolist<entity, dto>(); }
3. Entity Framework Structure
Based on the purpose of convenient management, each module can be used to organize the business content of the module in a fixed hierarchical way, each module is implemented in a perfectly formed policy. The project structure for the entire business logic layer of the instance module is as follows.
If we consider using WCF, then the overall structure is similar to my previous hybrid framework, and the responsibilities of each module are almost unchanged, but each implementation layer that was originally separated from the DAL layer changes to the mapping layer of each database, and the model adds DTOs, as shown in the project structure.
The specific project description is as follows:
Efrelationship |
The system's business modules and interfaces, database access modules and interfaces, DTO objects, entity class objects, various database mapping mapping classes and other related content. The module's content is tightly coupled with the code generated by the powerful code generation tool, the highly abstract inheritance of each layer, and the use of generics to support multiple databases (DATABASE2SHARP). |
Efrelationship.wcflibrary |
The business logic module of the system's WCF service, which puts the business management logic together to facilitate the deployment and invocation of WCF services by referencing file methods. |
Efrelationshipservice |
The framework WCF service modules, including the basic service module BASEWCF and the Business Services module, are distributed separately for ease of administration. |
Efrelationship.caller |
The façade application interface layer which is implemented by the specific business module is defined, and the project that wraps the WinForm invocation mode and the WCF call Way is made. |
Specifically, we take a member system design as an example, and its assembly relationship is as follows.
Let's take a look at the overall architecture design effect as shown below.
Where the Business Logic Layer module (and other application tiers) We provide a lot of the Entity Framework-based Common class library (WHC.Framework.EF), where the inheritance relationship we enlarge it to understand the inheritance details of the relationship, the effect is as follows.
It's a good overview of the design of my EF Entity Framework, which ultimately generates an integrated build through the code generation tool Database2sharp to improve the speed of production and unify all naming conventions. There is a chance to write an essay about the logical part of code generation later.
Two factory classes highlighted on the left, one ifactory is based on the local direct connection, which is the direct use of the EF framework of the object for processing; a callerfactory is an interface based on the facade layer, which points to the WCF Data service object according to the configuration. or direct-attached objects to manipulate the data.
This series of articles is as follows:
The formative journey of Entity Framework entities--the Entity Framework based on the generic storage model (1)
The formative journey of Entity Framework entities--optimizing Entity Framework with Unity object Dependency Injection (2)
The formation journey of Entity Framework entities--the implementation of unified and asynchronous operation of the base class interface (3)
The formation of Entity Framework entities frame--processing of Entity Data Model (EDM) (4)
The formation of Entity Framework entities frame Design--code first (5)
The formation of Entity Framework Entities frame Tour--code first mode using the Fluent API configuration (6)
The formative journey of Entity Framework entities--data transmission model the separation and union of DTOs and entity model entities
The formative journey of Entity Framework entities--data transmission model the separation and union of DTOs and entity model entities