Reduce entity classes derived everywhere

Source: Internet
Author: User

The entity classes here tend to be data transmission objects (DTO ). Whether the encoding style adopts the transaction script or domain model, we will encounter a variety of data transmission objects, especially in the encoding of the Three-layer architecture of the traditional transaction script, we will also encounter various types of entity objects, generally, these entity objects are generated for the following reasons:

1. Join table queries for various reports and query services may result in more fields and more entity attributes. What should I do? Create a new object class or add fields to the original object class?

2: Different DTO objects (such as JSON objects) will be created and transferred to the background for different requirements at the front-end, when a new object is generated, create a new object class or add a field to the original object class?

Most of us will encounter these problems. The following are some measures to avoid creating a new object class or adding fields to the original object class.

First, let's look at the first situation.

I. The number of fields in the join Table query increases.

This is the process from the internal (data layer) to the external (UI Layer.

We used to code like this:

Public override IList <User> GetList ()
{
String SQL = "select * from [EL_Organization]. [User] where state = 1 ";
Var ds = SqlHelper. ExecuteDataset (
SqlHelper. ConnectionString,
CommandType. Text,
SQL );
Return DataTableHelper. ToList <User> (ds. Tables [0]);
}

Now, we use the anonymous type:

Public IEnumerable GetList2 ()
{
String SQL = "select * from [EL_Organization]. [User] where state = 1 ";
Var ds = SqlHelper. ExecuteDataset (
SqlHelper. ConnectionString,
CommandType. Text,
SQL );

Var oblist = new List <object> ();
Foreach (DataRow row in ds. Tables [0]. Rows)
{
Oblist. Add (new {Id = row ["Id"], Name = row ["Name"]});
}

Return oblist;
}

You may notice two changes,

First, we used the generic + Reflection Method (general method, do not go into details) and directly returned the IList <User>. Now, we do not have such a general method, only one foreach loop can be used to construct such an anonymous type and its list. You may first worry about the tedious and mechanical code in the loop, but it must be simpler than creating a new type. Second, you may think of transforming the original generic + Reflection Method to support the anonymous type, but when I write this function, I am a little worried about its efficiency, so I still recommend the above method.

Second, change: the return type is IEnumerable, replacing the original IList <User>. This seems to have sacrificed some features that were originally forced, but these features are insurmountable. One way is to change the return type to IList <dynamic>, but this still causes a little performance loss, so I still recommend that you do not have to make it necessary (for example: in the business layer, You need to assign values to the returned results). It is sufficient to return IEnumerable.

Now, the Dal layer is like this. How can we use the last caller? Take the Controller in MVC as an example. We should use the following method (Note: The following method is for an IEnumerable upper-layer response type, if List <dynamic> is returned, refer to "JSON serialization of ExpandoObject "):

Public JsonResult xTest ()
{
UserDal dal = new UserDal ();
Var list = dal. GetList2 ();
Return this. Json (list, JsonRequestBehavior. AllowGet );
}

You may think that this is too simple. If you extract it from the DAL layer, it will be thrown to the front-end. Yes, this is often the case when the transaction script is encoded. Even if you still need to perform special processing on the DAL return value, using the anonymous type will not stop us from doing anything.

 

2. construct different objects (such as JSON objects) and transfer them to the background

We know that if the Controller in MVC contains a strongly typed parameter, the MVC engine will automatically convert the JSON object post to this type. For example, the background is like this (that is, the strong type is declared in the parameter ):

Public class xTemp
{
Public string XId {get; set ;}
Public string XName {get; set ;}
}

Public JsonResult xTest (xTemp SomeData)
{
...
Return this. Json (easyUiPages, JsonRequestBehavior. AllowGet );
}

And the front-end is like this:

Var SomeData = {
"XId": "xxx ",
"XName": "zzz"
};
$. Ajax ({
Type: "post ",
Data: SomeData,
Url: "@ ViewBag. Domain/home/xTest ",
Success: function (data ){
;
}
});

Then our background will parse this object. However, if we change the declaration of SomeData in the Controller to object or dynamic, we will not get anything. Therefore, if you do not want to create a new type, you can use the following methods:

1: Get object attributes one by one

Directly pass or create a dynamic object, and then pass it to The bll or dal layer for processing. Generally, there are fewer than three object attributes to be processed.

2: Or, honestly create an object.

Traditionally, we have at least three options: Creating ViewModel or domain entity or data entity.

2.1 ViewModel refers to the objects on the UI Layer. By default, a folder of ViewModel is created on the UI Layer for placement. These objects are not dispersed to other layers. Of course, you can transmit dynamic to the lower layer;

2.2 domain entity refers to the entity at the business logic layer, or we also call it a business entity. Business entities and business classes are placed together in parallel. The upper layer (such as the UI Layer) is accessible, and the lower layer is inaccessible;

2.3 data entities refer to the bottom-layer entities that can be accessed by the DAL layer. They are generally used to map database tables (navigation attributes such as EntityFramework are used for table join operations ), however, some common entity classes can also be placed at this layer. Note: domain entities can also be used as data entities;

In some small applications, ViewModel, domain entity, and data entity are often integrated into the entity layer. In short, the creation and placement of the entity layer must be very clear. The creation and placement of entity classes at Will will lead to code expansion and bring disaster to refactoring.

If we find that the data entity is not enough, the recommended roadmap here is:

1. Modify the data entity or create a new data entity;

2: if the data entity cannot be moved or does not want to be moved, A ViewModel is created;

3: If the business class needs to use this object, the ViewModel is restructured into a domain entity;

4: If we find that the object is to be passed to the DAL layer, we have four options,

4.1 manually convert to a data entity;

4.2 go back to the first step and reconstruct the entity into a data entity;

4.3 Use dynamic to pass to the Dal layer;

4.4 pass attributes as parameters;

The practice of creating redundant entities can be seen that we have talked so much about it. If you already feel bored or feel that you cannot grasp this level, so our ultimate practice is the following.

3: receives JSON strings and deserializes them into dynamic.

We mentioned above: if the declaration of SomeData In the controller is replaced with an object or dynamic, we will not get anything. However, we can do this,

Frontend data: SomeData, for example:

Data: "someData =" + JSON. stringify (SomeData)

Note: because we actually pass a string here, we cannot declare it:

ContentType: "application/json; charset = UTF-8 ",

The background is:

[SessionFilter]
Public JsonResult XTest (string someData)
{
Var jsSerializer = new JavaScriptSerializer ();
Var model = jsSerializer. Deserialize (somData, typeof (dynamic) as dynamic;
// If it is a list, it is processed as follows:
// Var models = jsSerializer. Deserialize (somData, typeof (List <dynamic>) as List <dynamic>;

Omitted
Return this. Json (result, JsonRequestBehavior. DenyGet );
}

This is a recommended and effective way to reduce entity types.

 

3. Another idea: Build a common entity class

The central idea of this idea is to eliminate all entity classes. Any traditional entity is nothing more than: type name + attribute value. Therefore, we construct such a general entity class, for example:

[Serializable]
Public sealed class DynamicDalObject: DynamicObject, IDictionary <string, object>
{
Public DynamicDalObject ()
{
This. _ inner = new Dictionary <string, object> (StringComparer. OrdinalIgnoreCase );
}

Public DynamicDalObject (IEnumerable <KeyValuePair <string, object> keyValuePairs): this ()
{
Foreach (var keyValuePair in keyValuePairs)
{
This. _ inner. Add (keyValuePair );
}
}

......
}

Then, to the DAL layer, you can perform the following operations:

Public static int Update (bool isOnline, int viewdCount, string Id)
{
Using (var manger = new DynamicDalSqlManager ())
{
Return
Manger. DataAccess. Update (
New DynamicDalObject (
New []
{
New KeyValuePair <string, object> ("id", Id ),
New KeyValuePair <string, object> ("IsOnline", isOnline ),
New KeyValuePair <string, object> ("ViewdCount", viewdCount ),
}),
"EL_Course.CourseHistory ",
New [] {"id "});
}
}

Advantages:

1: as long as you do not want to use the entity class, use it to solve it;

2: Common Dal can be built, that is, only one DAl is enough;

Disadvantages:

1: The object-oriented structure is lost, and it actually becomes SQL-oriented;

2: Non-stop unpacking and packing;

This kind of common entity class can be used in some cases where the business is relatively simple and can bring a short and fast effect.

 

Iv. Summary

In short, the anonymous and dynamic types should be fully utilized to reduce unnecessary or ambiguous entity classes. Finally, the suggested architecture ideas should be clarified:

1: first, we have a data entity layer, which can be expanded;

2: If the existing entity cannot meet the needs, the anonymous type can be used from the DAL to the UI;

3: if the existing entity cannot meet the requirements, the deserialization from the client to the controller can be a JSON string (non-object) and of the dynamic type in the Controller;

4: If a service method is used in multiple scenarios, you can reconstruct its dynamic object into a data entity (priority) or domain entity. Why is data entity given priority? Because this strong object can be passed directly from the business layer to the DAL layer.

5: In the domain model, the DTO object applies to this suggestion.

Related Article

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.