In the previous article, we analyzed several classes in common. These classes are used for auxiliary purposes. In fact, they are not very important. This makes it important for us to analyze these classes today, it includes entity, idatabase, and ientitydataaccess. Among them, entity serves as the base class of all entity classes, which is even more important. While idatabase and ientitydataaccess serve entity classes.
First look at the familiar system structure.
Entity, idatabase, and ientitydataaccess are in the business layer. The current class diagram of this layer is as follows:
We can see that the business layer contains the blog and blogclass entity classes, both of which are inherited from the entity class. Each entity class (including the entity) corresponds to an entension class, this class is naturally the place where the extension methods related to this class are stored. It is usually an extension of the iqueryable and ientityaccess interfaces. In addition, the idatabase and ientityaccess interfaces define the database access methods.
1. entity class. Entity is the base class of all entity classes. It is a template class and cannot be a struct generic class. It provides the attributes of ID, timestamp, and isnew for all object classes. The validate, save, and delete methods. Each method also includes the actual operations validateaction, saveaction, and deleteaction.
1. attributes:
The ID and timestamp attributes are abstract attributes. This is because the inheritance of LINQ is not very mature, so we postpone the specific information of ID and timestamp for each entity class (usingCodeIn this way, for LINQ, there is no entity system inherited. In addition, the ID and timestamp are read-only, and the content of the field can be set through reflection. Therefore, we set the ID and timestamp to read-only. Only the value of these two fields is the responsibility of LINQ, this technique can be used to prevent external modification of a class. It can also be used for other attributes that do not allow external modification of the class (that is, only attributes of the get method are included ). The isnew method is based on the ID field. See the following code. Because the ID is read-only, we can safely identify whether the field is new or read from the database by determining whether the ID is 0.
1:/// <Summary>
2:/// ID of the new object
3:/// </Summary>
4:Public Const IntNew_entity_id = 0;
5:/// <Summary>
6:/// Obtain whether the object is a new object
7:/// </Summary>
8:Public BoolIsnew
9:{
10:Get {ReturnId = new_entity_id ;}
11:}
2. Method:
Entity provides three methods: validate, save, and delete. Each method contains the actual operations that can be overwritten by the quilt class: validateaction, saveaction, and deleteaction. This is usually the case between the two:
1:/// <Summary>
2:/// Verify
3:/// </Summary>
4:/// <Param name = "Database"> database </param>
5:/// <Returns> Verification Result </returns>
6:PublicValidateresult validate (idatabase database)
7:{
8:If(Database =Null)
9:Throw NewArgumentnullexception ("Database");
10:
11:VaR validater =NewValidater ();
12:Validateaction (validater, database );
13:ReturnValidater. Validate ();
14:}
15:/// <Summary>
16:/// Verification Action
17:/// </Summary>
18:/// <Param name = "validater"> validators </param>
19:/// <Param name = "Database"> database </param>
20:Protected Virtual VoidValidateaction (validater, idatabase database ){}
That is, entry methods such as validate provide common operations such as verification parameters, and provide them to actions that can be rewritten by subclass. The Save method is special among the three methods. Before executing the action, it calls the validate method to ensure that all the data saved to the database is legal. As follows:
1:Public VoidSave (idatabase database)
2:{
3:If(Database =Null)
4:Throw NewArgumentnullexception ("Database");
5:
6:VaR validateresult =This. Validate (database );
7:If(! Validateresult. isvalidated)
8:Throw NewValidatefailexception (validateresult );
9:
10:Saveaction (database );
11:}
The parameters of validate, save, and delete are all idatabase interfaces, which define all operations to be performed by the database, it should be said that it is a very coarse-grained interface (although this interface only has one method ). The advantage of using a coarse-grained interface is that the entity class can access the entire database for easy use when processing its own data. Logically, the three methods use the database as the parameter, indicating that the validate, save, and delete operations are performed in the data context environment, which is also very clear. The subsequent operations on the database will take this coarse-grained interface as the parameter. However, you should also note that the implementation mechanism should not be too bloated, otherwise too many instances will affect the system performance, we use lazy load to solve this problem, when analyzing the implementation of data access, we will return to this issue.
Entityextension this class provides a very common extension method: Get Objects Based on ID:
1:/// <Summary>
2:/// Obtain the object by ID
3:/// </Summary>
4:/// <Typeparam name = "T"> entity type </typeparam>
5:/// <Param name = "query"> Object Query </param>
6:/// <Param name = "ID"> id </param>
7:/// <Returns> the corresponding object. If the object does not exist, null is returned. </returns>
8:Public StaticT getbyid <t> (ThisIqueryable <t> query,IntID)
9:WhereT: entity <t>
10:{
11:If(Query =Null)
12:Throw NewArgumentnullexception ("Query");
13:
14:ReturnQuery. singleordefault (entity => entity. ID = ID );
15:}
With this method, you can use this method to obtain a blog: database. getdataaccess <blog> (). getbyid (1 );
This method will be further simplified to: database. Blogs. getbyid (1 );
Today, we have analyzed the code and design method of the entity base class. In the next article, we will focus on the design and implementation of the two interfaces for data access.
Code download