The previous article discussed in detail the use of the basic mapping of fluentnhibernate, its basic usage is the same as NHibernate, first to create a database link configuration file, then write the table mapping, and finally write the unit Test to see if the module mapping executed successfully. Fluentnhibernate the replacement of NHibernate is not only because of the mapping configuration file optimization, in addition, it can optimize the database link XML and avoid mapping file writing, This fully automated programming approach is automapping,fluentnhibernate encapsulates the method of automated mapping, so that developers only need several modifications to the table, without taking into account the conversion process of the data model to the object model.
If automapping is used in the project, then its specific architecture diagram is as follows
The above architecture diagram uses automapping, which can avoid the complex mapping file writing, that is nhibernate to access the database first from the fluentnhibernate to get the object and the data is how to convert each other, The fluentnhibernate then gets the rules of the mappings from the automapping, meaning that the automapping only needs to rewrite the mapping rules of the object model to achieve full mapping, which makes the development of the program quite simple.
First, automapping
The above uses the structure diagram to Fluentnhibernate's automapping to do the preliminary interpretation, can see automapping is attached to Fluentnhibernate, And Fluentnhibernate is attached to the nhibernate, the three of them first is nhibernate first work, find Fluentnhibernate, Then fluentnhibernate finds the rules for automapping and maps them according to the rules.
Often in development we will put mapping and models into the core of the assembly, for other layers of assembly calls, such as the repository layer, is a series of operations on the database, are encapsulated in the layer.
1.1 automapping Detailed
In the absence of automapping, if you use Fluentnhibernate to implement the mapping, you first create the mapping file and then write mapping code for each entity, but it's too much trouble. Because if there are many tables written mapping is a waste of time, but also generate a lot of redundant code, so this time you can consider using automapping to map files, just need to follow the rules created to create the database.
(1) Create a automapping mapping configuration class, Inherit the Defaultautomappingconfiguration class, and override the Shouldmap method to specify the namespace where the entity class resides
(2) Implement the mapping interface, define the entity to table automatic mapping rules, the main interface is as follows:
The Iclassconvention,entity class-to-table mapping requires the Apply method that specifies the table name, by default, as the table name for the Entity name.
Iidconvention,entity class to Table ID mapping rules, need to implement the specified table ID generated rules and ID generation rules, if not implement the interface, by default, the "Entity name _id" form the ID of the table.
Ireferenceconvention,entity class to table foreign key column mapping rules, you need to implement the Apply method to specify the foreign key column name generation rules and connection object loading rules, by default, the "Foreign Key object _id" form the foreign key column.
The Ipropertyconvention,entity class attribute to the table column name generation rule and load rule, by default, is the name of the table as the column name.
Ihasoneconvention,entity class One-to-one mapping rules and column generation rules, you need to implement the Apply method to specify the foreign key column naming rules, but also the foreign key object loading and operation mode, by default, "Object _id" form named.
Ihasmanyconvention,entity class One-to-many mapping rules and the generation rules of the column, you need to implement the Apply method to specify the name of the column rules, but also the foreign key object loading and operation mode, by default, "Object _id" form named.
Ihasmanytomanyconvention,entity class Many-to-many mapping rules and the generation rules of the column, you need to implement the Apply method to specify the associated table and the name of the column in the associated table, by default, "Object _id" form the name of the column, "Object to Object" The form names the table name.
(3) Write the configuration file for the unit test run automapping, generate the NHibernate mapping XML, and see if the mapping was successful.
The note:automapping mapping process generates redundant or redundant columns, as in many-to-many mappings, because there is a reference to the object at the end of the object, the table structure is generated with two associated tables, but only one associated table is used in the data. So if it is not necessary to use automapping to map the table structure, in some particularly small projects can consider the use of automapping, large projects recommend the manual creation of mapping files, so that you can manually control.
1.2 Detailed examples
A detailed discussion of the use of automapping is given above, and next we will create a code example to discuss how the automapping is used.
Here also the data structure diagram of the above-mentioned example to discuss in detail the use of automapping, the example used in the automapping automatically generated database structure diagram is as follows:
Is the use of automapping to map entity generated database structure diagram, the diagram includes a pair of one or one-to-many, many-to-many relationship, these relationships are generated in accordance with the 1.1 of the mapping rules are implemented, the specific use of the method will be described in detail in the development steps described above.
1.2.1 Creating a automapping configuration fileWhen using nhibernate for development, we first create a mirror session of a database, and when using fluentnhibernate, we first create a session object of the database, and then implement the data operation by turning the object into a persistent state.
The automapping configuration file creates the Autopersistencemodel object first when the session is created, that is, the assembly/namespace where the entity class resides and the entity-to-table mapping rules are registered to In Fluentnhibernate's automapping, the specific code is as follows:
<summary>///inherit the default Automapping configuration class///Override Shouldmap method to specify the namespace where the entity is mapped///</summary>public class storeconfiguration:defaultautomappingconfiguration{public override bool Shouldmap (type type) {return type . Namespace = = "Classlibrary1.mapping"; }}///<summary>///Create sessionfactory///</summary>public class build{private static Autopersistencemodel Cr Eateautomappings () {//automap.assembly ("Assembly.Load (" ClassLibrary1 "), New Storeconfiguration ())//Add need mapping The default defaultautomappingconfiguration can also be inherited by the class override Shouldmap method to specify the mapped namespace, return Automap, when it is added. Assembly (Assembly.Load ("ClassLibrary1"), New Storeconfiguration ())//conventions.setup () method is to bind the specific rules of the mapping to the Automapp ING configuration, the following configuration://defualttablenameconvertion default table naming method//defaultprimarykeyconvention default primary key naming method /defualtstringlengthconvertion the default string length//defaultreferenceconvention the default foreign key creation method//defaulthasmanyconvent IonA one-to-many creation method//defualthasoneconvertion the default one-to-one creation method//hasmanytomanyconvention the default many-to-many creation method. Conventions.setup (con = {con. Add<defualttablenameconvertion> (); Con. Add<defaultprimarykeyconvention> (); Con. Add<defualtstringlengthconvertion> (); Con. Add<defaultreferenceconvention> (); Con. Add<defaulthasmanyconvention> (); Con. Add<defualthasoneconvertion> (); Con. Add
With the above configuration code can implement automapping rules, but often our configuration file needs to implement the mapping interface, by implementing these interfaces to define the entity and table mapping rules, After implementing these interfaces, add these classes to setup to the appropriate automapping.
1.2.2 Implementing a mapping interfaceAfter adding the automapping configuration file, it is basically possible to implement the mapping, but if we do not have a custom mapping rule, the corresponding table structure will be generated by default, and the resulting table structures can also customize these rules by implementing interfaces, as follows.
(1) iclassconvention
By implementing this interface to define mapping transformation rules for the mapped entity class to table, the default is to use the object name as the table name if the build rule is not overridden. The implementation method of the specific definition is as follows code:
public class defualttablenameconvertion:iclassconvention{ //<summary>///Specify the generated table name or table name-to-object mapping // /</summary>// <param name= "instance" > Entity object to be mapped </param> public void Apply ( FluentNHibernate.Conventions.Instances.IClassInstance instance) { //Defines the rule that generates the table name, the entity class name +s instance. Table (instance. Entitytype.name + "S");} }
(2) Iidconvention
Implement this interface to define mapping rules for the attribute column in the entity class of the map to the table ID, as well as to specify the rule for the ID, by default the ID of the table is named "Entity name _id".
public class defaultprimarykeyconvention:iidconvention{//<summary>/// Specify the build rule for entity class to table ID , and the Rules for ID///</summary>// <param name= "instance" > Generate entities for Objects </param> public void Apply ( FluentNHibernate.Conventions.Instances.IIdentityInstance instance) { instance. Column (instance. Entitytype.name + "ID"); Instance. Generatedby.native (); }}
(3) Ireferenceconvention
Implement this interface to specify the foreign key column mapping rules for the entity class to table, which by default names the foreign key column in the form of foreign key object _id.
public class defaultreferenceconvention:ireferenceconvention{//<summary>///// Specify the generation rules for the foreign key of the object// </summary> //<param name= "instance" > Foreign key Objects </param> public void Apply (imanytooneinstance Instance) { instance. Column (instance. Name + "ID"); Instance. Lazyload (); }}
(4) Ipropertyconvention
The Entity class property to the table column name generation rules and load rules, you can also define the database column type of the generated rules, by default, the property name as the column name of the table.
public class defualtstringlengthconvertion:ipropertyconvention{ //<summary>//Configuration table column name and type //</summary> //<param name= "instance" > Properties of Objects </param> public void Apply ( FluentNHibernate.Conventions.Instances.IPropertyInstance instance) { //Set column string length is instance. Length (a); }}
(5) Ihasoneconvention
Entity class One-to-one mapping rules and column generation rules, but also can specify the foreign key object loading and operation mode, by default will be named "Object _id" form.
public class defualthasoneconvertion:ihasoneconvention{ //<summary>///one-to-one mapping of foreign key columns and types of operations from tables </summary> //<param name= "instance" > Relational objects </param> public void Apply (ionetooneinstance Instance) { //Specifies the column name rule instance for the Foreign key column . ForeignKey (instance. Entitytype.name + "ID"); Specifies that the primary table instance the operation from the table . Cascade.saveupdate (); Instance. Lazyload (); }}
(6) Ihasmanyconvention
Entity class is a one-to-many mapping rule and a column generation rule, as well as a way to specify how foreign key objects are loaded and manipulated by default, named "Object _id".
public class defaulthasmanyconvention:ihasmanyconvention{//<summary>/// Multiple object generation rules/// </ Summary> //<param name= "instance" ></param> public void Apply (ionetomanycollectioninstance Instance) { instance. Key.column (instance. Entitytype.name + "ID"); Instance. Cascade.alldeleteorphan (); Instance. Lazyload (); }}
(7) Ihasmanytomanyconvention
Entity class Many-to-many mapping rules and column generation rules, by default, name the column name in the form "Object _id" and "object to object" as the name of the table.
public class hasmanytomanyconvention:ihasmanytomanyconvention{//<summary>/// Many-to-many mappings rules// </summary> //<param name= "instance" > Many-to-many relationship instances </param> public void Apply ( Imanytomanycollectioninstance instance) { //Specifies the table name of the build rule, the table name is sorted by character smaller table name in front, the table name is larger than the instance. Table (instance. EntityType.Name.ToString () +instance. ChildType.Name.ToString ()); The name of the party of the associated column is instance. Key.column (instance. EntityType.Name.ToString () + "ID"); The other side of the series is named instance. Relationship.column (instance. ChildType.Name.ToString () + "ID");} }
1.2.3 Writing the unit test test mapThe mapping rules for automapping are discussed in detail above, and the Code for mapping rules of automapping in mappings is added, and the rules of mapping are actually quite simple to implement the corresponding mapping rules. If you do not rewrite the mapping rules, the database table structure will be generated by default, so when creating the table structure, you need to create the table structure according to certain rules, and then follow the rules of the table structure you created to create the corresponding mapping rule configuration file, such as the code above, then we write the unit Test for automapping.
Once the rule is created, you need to run the automapping file once and set the configuration file to the following code:
Public Isessionfactory Createsessionfactory () {return fluently. Configure ()////Create or specify the configuration XML for the database, which uses the method of auto-creation//Specifies the mapping method of the database, in fact its underlying use is reflection to implement the mapping. Database (mssqlconfiguration. MsSql2005. ConnectionString ("Data source=.;i Nitial catalog=mapping;integrated security=true; Pooling=true; Min Pool size=20; Max Pool size=60 ")//Specify the connection string. Showsql ())//configure mapping rules. Mappings (M = M.automappings.add (Createautomappings ())//Adds the Autopersistencemodel object created to automapping. Exportto ("C:\\path")//export Map file)//Generate database Schema//new schemaexport (CFG). Create (True, false) creates a configuration file. Here the Create method is the mapping method of the created script file,//First parameter bool script specifies whether to generate database script//second parameter bool export specifies whether the creation script for each generated database executes . Exposeconfiguration (cfg = new Schemaexport (CFG). Create (True, True)). Buildsessionfactory (); }
This will retrieve the table structure of the database each time it is run and create the corresponding database table structure, so it should be changed after running once. Exposeconfiguration (cfg = new Schemaexport (CFG). Create (True, false)).
Use the unit test method to test one-to-one mappings as follows:
[Testfixture]public class unittest1:build{ [Test] public void Testusers_userdetails () { Isessionfactory sessionfactory = Createsessionfactory (); ISession Session = Sessionfactory.opensession (); Get user from database //user user1 = session.load<user> (2); Save the User Data Session.Transaction.Begin (); User Usreuser = session.get<user> (2); User user = new User () { Name = "Jack", No = "12321" }; Userdetail userdetails = new Userdetail () {Age = a, BirthDate = DateTime.Now.Date, Height = 240,< C20/>sex = 1 }; User. Userdetails = userdetails; Userdetails.user = User; Session.save (user); Session.save (userdetails); Session.Transaction.Commit (); }}
The database tables generated after running the unit Test method are as follows:
The data for the table structure that was inserted after the run is complete, such as:
Writing code to test many-to-many mapping relationships is as follows:[Testfixture]public class unittest1:build{[Test] public void Testusers_userdetails () {isessionfactory SE Ssionfactory = Createsessionfactory (); ISession session=sessionfactory.opensession (); Get user from database//user user1 = session.load<user> (2); Save the User data Session.Transaction.Begin (); User Usreuser = session.get<user> (2); User User=new User () {Name = "Jack", No = "12321"}; Userdetail userdetails=new Userdetail () {age = a, BirthDate = DateTime.Now.Date, Height = +, Sex = 1}; User. Userdetails = userdetails; Userdetails.user = User; Session.save (user); Session.save (userdetails); Session.Transaction.Commit (); } [Test] public void Testusers_productproject () {isessionfactory sessionfactory = Createsessionfactory (); ISession session = Sessionfactory.opensession (); Get user from database//user user1 = session.load<user> (1); Save the User data Session.Transaction.Begin (); Project Project = new Project () {Name = "Project1"}; Product Product1 = new Product () {Name = "Product1", Color = "Red",}; Product Product2 = new Product () {Name = "Product2", Color = "Red"}; Product1. Project.add (project); Product2. Project.add (project); Project Project1 = new Project ()//{//Name = "Project2"//}; Project. Product.add (PRODUCT1); Project. Product.add (PRODUCT2); Session.save (project); Session.save (PRODUCT1); Session.save (PRODUCT2); Session.Transaction.Commit (); } [Test] public void testusers_projectproduct () {isessionfactory sessionfactory = createsessIonfactory (); ISession Session = Sessionfactory.opensession (); Get user from database//user user1 = session.load<user> (1); Save the User data Session.Transaction.Begin (); Project Project = new Project () {Name = "Project1"}; Project Project1 = new Project () {Name = "project2"}; Product Product = new Product () {Name = "Product1", Color = "Red",}; Product. Project.add (project); Product. Project.add (Project1); Project. Product.add (product); Project1. Product.add (product); Session.save (project); Session.save (Project1); Session.save (product); Session.Transaction.Commit (); }}
After running two methods, view the resulting data as follows:
Conclusion
This paper discusses the use of automapping in detail, mainly discusses the use of automapping and uses the database structure in the previous article as an example to demonstrate the implementation of the Automapping code, the source of the project is:/http download.csdn.net/detail/zhang_xinxiu/8309201.
Although using automapping to implement the mapping is simple and can reduce the redundancy of the code, it is not recommended to use this method for mapping in large projects because automapping has too much uncertainty, is not mature enough, and there is little data to be queried. To avoid risk, it is recommended to use Fluentnhibernate to map projects.
"The Path of Architecture orm"--fluentnhibernate automapping detailed