After two articles: "Opening" and "simple ing"ArticleI believe you have some knowledge about fluent nhib. fluentnhib is actually an extension of the nhib ing, we can make full use of strong type, generic, lambde expressions, etc. Vs, framework, and other features to easily complete the ing work. At the same time, we can also learn the nhing method of Nhibernate to win the game, is there a reason not to continue to complete this series? Don't talk nonsense, go back to the subject.
Starting from this article, we will use fluent nhib1_rc 1.0 for demonstration.Code, I will explain it separately
Inheritance
In Oop, inheritance is an important feature of OO. If nhib.pdf does not support it, how can it be called a complete ORM framework? So how can we implement inheritance through database design? There are three common methods. Today we will describe them one by one. I will not talk about the concept of inheritance. If you don't even know the concept of inheritance, you can learn it from the beginning.
- Table per class hierarchy (all subclasses are in one table)
- Table per subclass (one table for the parent class and one table for each subclass)
- Other (other methods)
Preparation
In the previous two articles on e-commerce, we cannot have only one product, but they have the same attributes, it is the best example that each product type has its own properties. For the same product attributes, refer to the previous article. Well, let's assume that our products have books and mobile phones, and they have their own properties. We simply add some attributes. The books have authors, and the mobile phones have brands and models, we write the two entity models:
Public classMobileproduct:Product{Public Virtual stringBrand {Get;Set;}Public Virtual stringNumber {Get;Set;}}Public classBookproduct:Product{Public Virtual stringAuthor {Get;Set;}}
Table per class hierarchy
In this way, we have learned about nhib.pdf. In fact, we put all the attributes of the parent class and subclass into a table. The advantage of this is that we do not need to create other tables, A table is all done, but its shortcomings are also obvious. There may be nothing in the case of few properties. However, when there are more, our maintenance and expansion become relatively troublesome, in addition, many redundant fields are generated, and we must add another identifier to differentiate them.
Because an identifier is required, we must add an identifier, which is represented by the enumeration type here. The code is changed to the following:
Public Enum Producttype {Mobile, book} Public abstract class Product {//...
Public Abstract Producttype Type { Get ;}} Public class Mobileproduct : Product {//... Public override Producttype Type {Get { Return Producttype . Mobile ;}}} Public class Bookproduct : Product {//... Public override Producttype Type { Get { Return Producttype . Book ;}}}
When designing a database, you should note that it is best to set the fields in the subclass to null to avoid the problem of being unable to insert. We also need to add an Identifier Field. I use tinyint,
The fluent ing is as follows:
Public class Productmap : Classmap < Product > { Public Productmap () {ID (P => P. productid); Map (P => P. createtime); Map (P => P. name); Map (P => P. price); discriminatesubclassesoncolumn < Producttype > ( "Type" , Producttype . Book );}} Public class Bookmap : Subclassmap < Bookproduct > { Public Bookmap () {discriminatorvalue ( "1" ); Map (P => P. Author );}} Public class Mobilemap : Subclassmap < Mobileproduct > { Public Mobilemap () {discriminatorvalue ( "0" ); Map (P => P. Brand); Map (P => P. Number );}}
Before the RC version, we can use
Discriminatesubclassesoncolumn <Producttype> ("Type",Producttype. Book). Subclass <Bookproduct> (B => {B. Map (P => P. Author );});
However, the RC version is not recommended for this purpose. A good way is to separate the subclass ing. You will know later, both the first and second strategies use this method for ing. As for ing, subclass is used. Fortunately, join-subclass is used, and fluentnhibass is automatically generated.
Let's talk about discriminatesubclassesoncolumn. This is a ing method of identifiers, because we can use the setattribate method before the RC version, set our parent class to "not-null", but in RC, this method has been completely discarded and we have to use the above method to give a default identifier. In the subclass, we must specify the corresponding Identifier value. Here we see a failure. We can only set the string type, my God, the setattribute in disguise, I think this is beyond the title of fluent (as described in the RC upgrade Introduction ).
PS: I have just read the latest fnt and fixed this bug. Now I have changed it to discriminatorvalue (object Value). Click
Let's take a look at the test code:
[Testmethod ] Public void Fluentcreatedata (){ VaR Factory = Fluentsessionfactory . Getcurrentfactory (); Using ( VaR Session = factory. opensession ()){ Product Nokia = New Mobileproduct () {Brand = "Nokia" , Number = "N91" , Createtime =Datetime . Now, price = 5600, name = "Nokia n91 mobile" }; Session. Save (Nokia ); Product Book = New Bookproduct () {Author = "Sixty-six" , Createtime = Datetime . Now, price = 20, name = "Dwelling" }; Session. Save (book );}}[ Testmethod ] Public void Fluentseletedata (){VaR Factory = Fluentsessionfactory . Getcurrentfactory (); Using ( VaR Session = factory. opensession ()){ VaR Product = session. createcriteria < Bookproduct > (). List < Bookproduct > (). Firstordefault (); Assert . Areequal ( "Dwelling" , Product. Name ); Assert . Areequal (20, product. Price );}}
Test results:
Table per subclass
In this way, a parent table includes some common attributes. In addition to the primary key, the child table only has its own attributes. This method has a clear table structure and does not contain any redundant fields. It is a good choice for convenient extension. However, this is not to say that other methods are useless. It depends on your use scenario. View table structure:
Note that the primary key of the sub-table is not incremental (nonsense, haha ).
On mapping:
Public class Productmap : Classmap < Product > { Public Productmap () {ID (P => P. productid); Map (P => P. createtime); Map (P => P. name); Map (P => P. price );}} Public class Bookmap :Subclassmap < Bookproduct > { Public Bookmap () {table ( "Book" ); Keycolumn ( "Productid" ); Map (P => P. Author );}} Public class Mobilemap : Subclassmap < Mobileproduct > { Public Mobilemap () {table ( "Mobile" ); Keycolumn ("Productid" ); Map (P => P. Brand); Map (P => P. Number );}}
How is it? Is it similar to the first method? haha, thanks for this upgrade. We can switch between the two methods without too much change. It is very convenient, as for the deficiency, it may be that keycolum does not automatically identify it. Unfortunately, if it is not specified, the default value is "product_id ".
The test code is the same as the first method. You can view the test result directly:
Other methods
Table per concrete class (one table for each subclass). This method should use the Union-subclass label, but fnt does not support this method. Why, both in terms of structure and writing, it is a bad practice and should be avoided as much as possible. Therefore, fnt simply does not support it. If this method is really needed, then you can directly map classmap <t> separately. Joint queries may be complicated.
There are also several mixed methods, which are actually the combination of the first and second methods. This depends on different requirements. At the same time, you can also combine the above two ing methods, so we will not introduce them.
Summary
This time I talked about the inherited ing method. In fact, it was written very early. It happened that fluent nhib.pdf released the RC version, so I spent some time learning it. In general, this upgrade is very good, and there may be more bugs, but it does not affect our normal use, and the updates are very fast now, the following may be a few of some of the less common mappings and some troubles, but I feel that there are not many people using nhib.pdf in the garden, and there is not much attention, but it does not affect my determination to continue writing, this time, I was very touched by fnt by chance. There are a lot of good examples to learn from, and in the series, basically every example has written the test code, although ugly, but since I was a child, I have to develop this habit in the future.