ORM frameworks have been in use for a long time to eliminate the impedance mismatch that exists between the object and data models in an application. In essence, ORMs enable you to write code to perform CRUD operations sans the need of interacting with the underlying database provider directly. Thus, usage of ORMs help you to isolate the object model of your application from the data model. NHibernate stores the mapping information in XML format in.
|Published (Last):||5 December 2008|
|PDF File Size:||17.12 Mb|
|ePub File Size:||12.36 Mb|
|Price:||Free* [*Free Regsitration Required]|
Rather than writing XML documents. This allows for easy refactoring, improved readability and more concise code. It's these mapping files that Fluent NHibernate provides a replacement for.
Why replace HBM. While the separation of code and XML is nice, it can lead to several undesirable situations. How does Fluent NHibernate counter these issues? It does so by moving your mappings into actual code, so they're compiled along with the rest of your application; rename refactorings will alter your mappings just like they should, and the compiler will fail on any typos.
As for the repetition, Fluent NHibernate has a conventional configuration system, where you can specify patterns for overriding naming conventions and many other things; you set how things should be named once, then Fluent NHibernate does the rest. Each release is made available on NuGet, and you should use that if at all possible.
Binaries are also available for a short period from our CI server, teamcity. Our source-control is Git using Github , and you have two options available. If you plan on modifying Fluent NHibernate and contributing back to us, then you're best forking our repository and sending us a pull request.
You can find out more about that on the github guides site: forking and pull requests. The other option is a direct clone of our repository, but that will leave you in an awkward state if you ever do plan to contribute but it's fine if you don't. Again, we recommend forking our repository; if you don't want to do that, you can do a direct clone:.
All the source can be found in the main Fluent NHibernate solution, in the Example. FirstProject project. You need to have Fluent NHibernate already downloaded and compiled to follow this guide, if you haven't done that yet then please refer to the installation section above. For this example we're going to be mapping a simple domain for a retail company.
The company has a couple of stores, each with products in some products are in both stores, some are exclusive , and each with employees. In database terms, that's a Store , Employee , and Product table, with a many-to-many table between Store and Product. First, create a console application and reference the FluentNHibernate.
You can see the project structure that I used to the left. The Entities folder is for your actual domain objects, while the Mappings folder is where we're going to put your fluent mapping classes. Now that we've got our project setup, let's start by creating our entities. We've got three tables we need to map we're ignoring the many-to-many join table right now , so that's one entity per table.
Create the following classes in your Entities folder. Our Employee entity has an Id , the person's name split over FirstName and LastName , and finally a reference to the Store that they work in. There's two things that may stand out to you if you're unfamiliar with NHibernate. Firstly, the Id property has a protected setter, this is because it's only NHibernate that should be setting the value of that Id.
Secondly, all the properties are marked virtual ; this is because NHibernate creates "proxies" of your entities at run time to allow for lazy loading, and for it to do that it needs to be able to override the properties.
Product has an Id , its Name , Price , and a collection of Store s that stock it. Finally, we've got our Store entity. This has an Id and a Name , along with a collection of Product s that are stocked in it, as well as a collection of Employee s in the Staff list that work there. This entity has a little bit of logic in it to make our code simpler, that's the AddProduct and AddEmployee methods; these methods are used to add items into the collections, and setup the other side of the relationships.
If you're an NHibernate veteran then you'll recognise this; however, if it's all new to you then let me explain: in a relationship where both sides are mapped, NHibernate needs you to set both sides before it will save correctly. So as to not have this extra code everywhere, it's been reduced to these extra methods in Store.
Now that we've got our entities created, it's time to map them using Fluent NHibernate. We'll start with the simplest class, which is Employee.
All the following mappings should be created inside the Mappings folder. The mappings themselves are done inside the constructor for EmployeeMap , so we need to add a constructor and write the mappings.
To start with we've mapped the Id column, and told Fluent NHibernate that it's actually an identifier. The x in this example is an instance of Employee that Fluent NHibernate uses to retrieve the property details from, so all you're really doing here is telling it which property you want your Id to be.
Fluent NHibernate will see that your Id property has a type of int , and it'll automatically decide that it should be mapped as an auto-incrementing identity in the database - handy! For NHibernate users, that means it automatically creates the generator element as identity. There are a couple of new methods we've used there, Map and References ; Map creates a mapping for a simple property, while References creates a many-to-one relationship between two entities.
In this case we've mapped FirstName and LastName as simple properties, and created a many-to-one to Store many Employee s to one Store through the Store property.
NHibernate users: Map is equivalent to the property element and References to many-to-one. Again, there's a couple of new calls here. If you remember back to Employee , we created a many-to-one relationship with Store , well now that we're mapping Store we can create the other side of that relationship.
So HasMany is creating a one-to-many relationship with Employee one Store to many Employee s , which is the other side of the Employee. Store relationship. You've also just got your first taste of the fluent interface Fluent NHibernate provides. All and Table ; this is called method chaining, and it's used to create a more natural language in your configuration. The Table call is currently only required if you're doing a bidirectional many-to-many, because Fluent NHibernate currently can't guess what the name should be; for all other associations it isn't required.
That's the Product mapped; in this case we've used only methods that we've already encountered. The HasManyToMany is setting up the other side of the bidirectional many-to-many relationship with Store. Write for the various relationships on a Store but you can see it in the full code. This is the Main method from your Program. It's a bit lengthy, but what we're doing is creating a couple of Store instances, then adds some Employee s and Product s to them, then saves; finally, it re-queries them from the database and writes them out to the console.
You won't be able to run this yet, because there's one thing left to do. Now we're going to use the Fluent NHibernate Fluently. Configure API to configure our application. You can see more examples on this in the Fluent configuration wiki page. That's not quite right yet, we're creating a SessionFactory , but we haven't configured anything yet; so let's configure our database. There we go, we've specified that we're using a file-based SQLite database.
You can learn more about the database configuration API in the Database configuration wiki page. Just one more thing to go, we need to supply NHibernate with the mappings we've created.
To do that, we add a call to Mappings in our configuration. You should now be able to run the application and see the results of your query output to the console window provided that you've actually created the SQLite database schema; otherwise, see the Schema generation section below.
If you haven't manually created the schema for this application, then it will fail on the first time you run it. There's something you can do about that, but it needs to be done directly against the NHibernate Configuration object; we can do that using the ExposeConfiguration method.
Combine that call with a method to generate the schema, then you're able to create your schema at runtime. You can read more about this in the Fluent configuration wiki page. Skip to content. Getting started Jump to bottom. Fluent NHibernate also has several other tools, including: Auto mappings - where mappings are inferred from the design of your entities Persistence specification testing - round-trip testing for your entities, without ever having to write a line of CRUD Full application configuration with our Fluent configuration API Database configuration - fluently configure your database in code Fluent NHibernate is external to the NHibernate Core , but is fully compatible with NHibernate version 2.
Due to XML not being evaluated by the compiler, you can rename properties in your classes that aren't updated in your mappings; in this situation, you wouldn't find out about the breakage until the mappings are parsed at runtime.
Repetitive mappings - NHibernate HBM mappings can become quite verbose if you find yourself specifying the same rules over again. For example if you need to ensure all string properties mustn't be nullable and should have a length of , and all int s must have a default value of Simple example Here's a simple example so you know what you're getting into.
Length Add this ; Products. SaveOrUpdate barginBasin ; session. SaveOrUpdate superMart ; transaction. CreateCriteria typeof Store. Database SQLiteConfiguration. UsingFile " firstProject. ExposeConfiguration BuildSchema. Exists DbFile File. Pages You signed in with another tab or window. Reload to refresh your session.
You signed out in another tab or window.