NHibernate Review series Many-to-many Collection map
Source: Internet
Author: User
1. Create an association
Table Structure Reference nhibernate Review series 01. Use Tblpurchasegroup and Tbluser for many-to-many associations, and the association table is tblpurchasegroupuser.
The Purchasegroup and user class code and the mapping configuration file are at the bottom of the article. Run the following test code inside the Nhtest project
Code highlighting produced by Actipro Codehighlighter (freeware)
http://www.CodeHighlighter.com/
--> static void Main (string [] args)
{
Isessionfactory sessionfactory = new Configuration (). Configure (). Buildsessionfactory ();
ISession session = NULL;
ITransaction trans = null;
Try
{
Session = Sessionfactory.opensession ();
trans = session. BeginTransaction ();
User User1 = new User ("User1", "user1", New Hashedset < Purchasegroup > ());
Session. Save (user1);
User User2 = New User ("User2", "User2", New Hashedset < Purchasegroup > ());
Session. Save (User2);
User User3 = New User ("User3", "User3", New Hashedset < Purchasegroup > ());
Session. Save (USER3);
Purchasegroup group1 = new Purchasegroup ("01A", "01A", New Hashedset < User > ());
Group1. Users.add (user1);
Group1. Users.add (User2);
Session. Save (group1);
Purchasegroup group2 = new Purchasegroup ("701", "Branch purchase Group", New Hashedset < User > ());
Group2. Users.add (User2);
Group2. Users.add (USER3);
Session. Save (group2);
Trans.commit ();
}
Catch
{
if (trans!= null)
Trans. Rollback ();
}
Finally
{
Session. Close ();
}
Sessionfactory.close ();
After executing the above test code, not only added three user objects and two Purchasegroup objects, NHibernate automatically according to the configuration information in the mapping file, also added the association relationship in Tblpurchasegroupuser Association table.
2. Main map End Reverse end
First, notice that there is a inverse attribute on the set element in the configuration file indicating the direction of the association. The inverse property value is true in the User.hbm.xml file, indicating that user is the opposite end of this association, and Purchasegroup is the primary mapping end. The difference between the main map end and the reverse end, we can use the following code to run the results of the above to make a comparison:
Code highlighting produced by Actipro Codehighlighter (freeware)
http://www.CodeHighlighter.com/
--> trans = session. BeginTransaction ();
User user = New User ("User4", "User4", New Hashedset < Purchasegroup > ());
Purchasegroup group1 = session. Get < Purchasegroup > ("701");
if (group1!= null)
User. Purchasegroups.add (group1);
Session. Save (user);
Trans.commit (); The result of this code is that the object was added to the database, but the association of USER4 and 701 was not added to the association table (USER4). As can be seen from this comparison, modifications to the mapping relationship (new, deleted) must be done at the primary mapping end, otherwise it cannot be saved to the database. Therefore, in a two-way many-to-many map, it is important to know which primary mapping end and which is the reverse side.
3. Get the associated collection object
Now note that the previous test has added the following data to the associated table:
Next, take a look at how to get the Many-to-many collection object, first notice that the Lasy property is set to False under the set element of the User.hbm.xml and Company.hbm.xml files. Open SQL Server SQL Profiler to monitor executed SQL statements. Step through the following test statements and observe the SQL that is monitored in SQL Profiler.
Code highlighting produced by Actipro Codehighlighter (freeware)
http://www.CodeHighlighter.com/
Session = Sessionfactory.opensession ();
Purchasegroup Group = session. Get < Purchasegroup > ("01A");
if (group!= null && group. Users!= null)
{
IEnumerator < User > enm = group. Users.getenumerator ();
while (ENM. MoveNext ())
{
User user1 = Enm. Current;
Console.WriteLine ("ID: {0}/t/tname: {1}", User1.) UserID, User1. UserName);
}
}
Console.WriteLine ("");
User User2 = session. Get < User > ("user2");
if (user2!= null && user2. Purchasegroups!= null)
{
IEnumerator < Purchasegroup > enm = user2. Purchasegroups.getenumerator ();
while (ENM. MoveNext ())
{
Purchasegroup group2 = Enm. Current;
Console.WriteLine ("ID: {0}/t/tdescription: {1}", group2.) Purchasegroupid, group2. Description);
}
}
Session. Close ();
Sessionfactory.close ();
Console.ReadLine ();
The test code above is working correctly, we use session. When the Get () method gets the Purchasegroup or user object, NHibernate automatically loads the associated collection object, so we can enumerate the group directly. Users and user2.purchasegroups to print the objects in the collection.
Result of SQL Profiler: executing purchasegroup group = session. Get < Purchasegroup > ("01A"); This line of code executes 6 SQL queries, and the rest of the code has no SQL. 6 SQL queries are as follows
Code highlighting produced by Actipro Codehighlighter (freeware)
http://www.CodeHighlighter.com/
--> sql1:exec sp_executesql N '
SELECT purchasegr0_. purchase_group_id as purchase1_1_0_, purchasegr0_. DESCRIPTION as Descript2_1_0_
From Tblpurchasegroup purchasegr0_
WHERE purchasegr0_. Purchase_group_id= @p0 ', n ' @p0 nvarchar (3) ', @p0 = n ' 01A '
Sql2:exec sp_executesql N '
SELECT users0_. purchase_group_id as Purchase1___1_, users0_. user_id as User2_1_,
User1_. user_id as user1_3_0_, user1_. User_name as user2_3_0_
From Tblpurchasegroupuser users0_
Left outer join Tbluser user1_ on users0_. User_id=user1_. user_id
WHERE users0_. Purchase_group_id= @p0 ', n ' @p0 nvarchar (3) ', @p0 = n ' 01A '
Sql3:exec sp_executesql N '
SELECT purchasegr0_. user_id as User2___1_, purchasegr0_. purchase_group_id as Purchase1_1_,
Purchasegr1_. purchase_group_id as purchase1_1_0_, purchasegr1_. DESCRIPTION as Descript2_1_0_
From Tblpurchasegroupuser purchasegr0_
Left outer join Tblpurchasegroup purchasegr1_ on purchasegr0_. Purchase_group_id=purchasegr1_. purchase_group_id
WHERE purchasegr0_. User_id= @p0 ', n ' @p0 nvarchar (5) ', @p0 = n ' user2 '
Sql4:exec sp_executesql N '
SELECT users0_. purchase_group_id as Purchase1___1_, users0_. user_id as User2_1_,
User1_. user_id as user1_3_0_, user1_. User_name as user2_3_0_
From Tblpurchasegroupuser users0_
Left outer join Tbluser user1_ on users0_. User_id=user1_. user_id
WHERE users0_. Purchase_group_id= @p0 ', n ' @p0 nvarchar (3) ', @p0 = n ' 701 '
Sql5:exec sp_executesql N '
SELECT purchasegr0_. user_id as User2___1_, purchasegr0_. purchase_group_id as Purchase1_1_,
Purchasegr1_. purchase_group_id as purchase1_1_0_, purchasegr1_. DESCRIPTION as Descript2_1_0_
From Tblpurchasegroupuser purchasegr0_
Left outer join Tblpurchasegroup purchasegr1_ on purchasegr0_. Purchase_group_id=purchasegr1_. purchase_group_id
WHERE purchasegr0_. User_id= @p0 ', n ' @p0 nvarchar (5) ', @p0 = n ' user3 '
Sql6:exec sp_executesql N '
SELECT purchasegr0_. user_id as User2___1_, purchasegr0_. purchase_group_id as Purchase1_1_,
Purchasegr1_. purchase_group_id as purchase1_1_0_, purchasegr1_. DESCRIPTION as Descript2_1_0_
From Tblpurchasegroupuser purchasegr0_
Left outer join Tblpurchasegroup purchasegr1_ on purchasegr0_. Purchase_group_id=purchasegr1_. purchase_group_id
WHERE purchasegr0_. User_id= @p0 ', n ' @p0 nvarchar (5) ', @p0 = n ' user1 ' SQL1: Get Purchasegroup object 01A
SQL2: automatically retrieves which user objects the 01A object is associated with according to the Tblpurchasegroupuser Association table to populate the 01A users collection.
SQL3: Two user User1 and User2 were obtained in SQL2, and the properties of these two users have been removed from the SQL2. However, NHibernate must also know which Purchasegroup objects User1 and User2 are associated with in order to generate complete User1, user2 two objects, and join the 01A users collection. This statement is primarily a query of the user2 associated Purchasegroup object from the Tblpurchasegroupuser.
The next SQL is similar to the one above, nested processing until the associated relationship terminates.
In the Execute User user2 = session. Get < User > ("User2"), this line of code, because the User2 object was previously created (and includes the complete user2). Purchasegroups Collection Object), there is no longer a need to execute SQL queries here (refer to the session cache mentioned in NHibernate in series 01).
Several conclusions: 1. The collection object is automatically fetched and the join statement is used. 2. Automatically populate the collection objects, so in a many-to-many association, the associated records are not too many, or you need to load too much data at a time. 2. Bidirectional many-to-many associations, which are nested to populate the collection object with special attention to this.
4. Lasy Delay Loading
Then look at the Lasy property and we set the lasy of the set element in User.hbm.xml and Company.hbm.xml files to True. Also note that, with deferred entity classes, attributes must be declared virtual, otherwise nhibernate throws an exception because NHibernate uses the proxy object to implement deferred loading. Run the following test code and also use SQL Profiler monitoring.
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.