{"id":35,"date":"2013-03-25T18:38:00","date_gmt":"2013-03-25T18:38:00","guid":{"rendered":"http:\/\/tpodolak.com.hostingasp.pl\/blog\/2013\/03\/25\/fluent-nhibernate-automappings\/"},"modified":"2016-01-30T23:52:12","modified_gmt":"2016-01-30T23:52:12","slug":"fluent-nhibernate-automappings","status":"publish","type":"post","link":"https:\/\/tpodolak.com\/blog\/2013\/03\/25\/fluent-nhibernate-automappings\/","title":{"rendered":"Fluent Nhibernate &#8211; automappings"},"content":{"rendered":"<h3>1. Introduction<\/h3>\n<p>Writing mappings for models in large application is quite boring task. Fortunatelly, Fluent NHibernate provides possibility for automatic mapping creation &#8211; so called automappings.<\/p>\n<h3>2. Creating database and model<\/h3>\n<p>In order to show you, how to configure automappings in Fluent NHibernate, let&#8217;s create simple database along with model classes. The database structure is presented in the picture below.<br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/DBDiagram.png\" rel=\"attachment wp-att-358\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/DBDiagram.png\" alt=\"DBDiagram\" width=\"450\" class=\"aligncenter size-full wp-image-358\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/DBDiagram.png 567w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/DBDiagram-150x96.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/DBDiagram-300x191.png 300w\" sizes=\"(max-width: 567px) 100vw, 567px\" \/><\/a><br \/>\nModel classes which represent database tables look this way<\/p>\n<pre lang=\"csharp\">\r\npublic abstract class ModelBase\r\n{\r\n    public virtual int Id { get; set; }\r\n}\r\n\r\npublic class Project : ModelBase\r\n{\r\n    public virtual string Name { get; set; }\r\n    public virtual User User { get; set; }\r\n    public virtual IList<Task> Tasks { get; set; }\r\n}\r\n\r\npublic class Task : ModelBase\r\n{\r\n    public virtual string Name { get; set; }\r\n    public virtual Project Project { get; set; }\r\n}\r\n\r\npublic class User : ModelBase\r\n{\r\n    public virtual string Name { get; set; }\r\n    public virtual string Surname { get; set; }\r\n}\r\n<\/pre>\n<h3>3. Automappings configuration<\/h3>\n<p>Having our database and models prepared, now we can create and configure SessionFactory to use automappings.<\/p>\n<pre lang=\"csharp\">\r\nvar factory = Fluently.Configure().Database(MsSqlConfiguration.MsSql2008.ConnectionString(\"YourConnectionString\"))\r\n                      .Mappings(val => val.AutoMappings.Add(AutoMap.AssemblyOf<Project>))\r\n                      .BuildSessionFactory();\r\n<\/pre>\n<p>As You can see I used the static AutoMap.AssemblyOf<T> method. This method takes a generic type parameter from which Fluent NHibernate can deduce which assembly to look in for mappable entities. From now all classes defined in the assemlby of <i>Project<\/i> are mapped using build-in convention.<\/p>\n<h3>4. Mapping only specified classes<\/h3>\n<p>Mapping all classes from specyfic assembly may not be very useful. That is why, we need to &#8220;tell&#8221; Automapper which classes should be mapped. It can be achieved by creating custom configuration class which implements <i>IAutomappingConfiguration<\/i> interface or which is subclass of <i>DefaultAutomappingConfiguration<\/i>. <i>IAutomappingConfiguration<\/i> interface has quite a lot of functions, that is why I decided to craete class which inherits from <i>DefaultAutomappingConfiguration<\/i> and override only one method &#8211; <i>ShouldMap<\/i><\/p>\n<pre lang=\"csharp\">\r\npublic class AutomappingConfiguration : DefaultAutomappingConfiguration\r\n{\r\n    public override bool ShouldMap(Type type)\r\n    {\r\n        return type.IsSubclassOf(typeof (ModelBase));\r\n    }\r\n}\r\n<\/pre>\n<p>As You can see by overriding <i>ShouldMap<\/i> function,I specified that only classes which inherit from <i>ModelBase<\/i> class should be mapped. To use our new configuration, we need to pass an instance of it to AutoMap setup<\/p>\n<pre lang=\"csharp\">\r\nvar factory = Fluently.Configure().Database(MsSqlConfiguration.MsSql2008.ConnectionString(\"YourConnectionString\"))\r\n                      .Mappings(val => val.AutoMappings.Add(AutoMap.AssemblyOf<Project>(new  DefaultAutomappingConfiguration())))\r\n                      .BuildSessionFactory();\r\n<\/pre>\n<h3>5. Defining custom conventions<\/h3>\n<p>It is rather obvious that default automapping conventions may not come along with our database naming conventions. Fortunately we can create custom conventions(which override default ones), and pass them to AutoMap configuration. Here are examples of conventions I use <i>IClassConvention<\/i> &#8211; gives us access to properties and functions which allow us to change a default table name format for our entities.<\/p>\n<pre lang=\"csharp\">\r\npublic class DefaultTableNameConvention : IClassConvention\r\n{\r\n    public void Apply(IClassInstance instance)\r\n    {\r\n        instance.Table(string.Format(\"{0}{1}\", \"GL_\", instance.EntityType.Name));\r\n    }\r\n}\r\n<\/pre>\n<p><i>IIdConvention<\/i> is used for altering default identity conventions.<\/p>\n<pre lang=\"csharp\">\r\npublic class DefaultPrimaryKeyConvention : IIdConvention\r\n{\r\n    public void Apply(IIdentityInstance instance)\r\n    {\r\n        instance.Column(\"Id\");\r\n        instance.GeneratedBy.Native();\r\n    }\r\n}\r\n<\/pre>\n<p><i>IPropertyConvention<\/i> &#8211; allows us to modify properties mappings (lazy load, nullability,length etc)<\/p>\n<pre lang=\"csharp\">\r\npublic class DefaultStringLengthConvention : IPropertyConvention\r\n{\r\n    public void Apply(IPropertyInstance instance)\r\n    {\r\n        instance.Length(50);\r\n    }\r\n}\r\n<\/pre>\n<p><i>IReferenceConvention<\/i> &#8211; allows us to modify entities relationship convention<\/p>\n<pre lang=\"csharp\">\r\npublic class DefaultReferenceConvention : IReferenceConvention\r\n{\r\n    public void Apply(IManyToOneInstance instance)\r\n    {\r\n        instance.Column(string.Format(instance.Class.Name.StartsWith(\"Id\") ? \"{1}\" : \"{0}{1}\", \"Id\",\r\n                                      instance.Class.Name));\r\n        instance.LazyLoad();\r\n    }\r\n}\r\n<\/pre>\n<p><i>IHasManyConvention<\/i> &#8211; allow us to modify default has-many relationship convention<\/p>\n<pre lang=\"csharp\">\r\npublic class DefaultHasManyConvention : IHasManyConvention\r\n{\r\n    public void Apply(IOneToManyCollectionInstance instance)\r\n    {\r\n        instance.Key.Column(string.Format(\"{0}{1}\", \"Id\", instance.EntityType.Name));\r\n        instance.LazyLoad();\r\n    }\r\n}\r\n<\/pre>\n<p>In order to use new conventions we need to pass them into AutoMap configuration.<\/p>\n<pre lang=\"csharp\">\r\nFluently.Configure()\r\n                .Database(\r\n                    MsSqlConfiguration.MsSql2008.ConnectionString(\"YourConnectionString\"))\r\n                .Mappings(val => val.AutoMappings.Add(AutoMap.AssemblyOf<Project>(new DefaultAutomappingConfiguration()).Conventions.Setup(con =>\r\n                                                                           {\r\n                                                                               con.Add<DefaultTableNameConvention>();\r\n                                                                               con.Add<DefaultPrimaryKeyConvention>();\r\n                                                                               con.Add<DefaultStringLengthConvention>();\r\n                                                                               con.Add<DefaultReferenceConvention>();\r\n                                                                               con.Add<DefaultHasManyConvention>();\r\n                                                                           })))\r\n                .BuildSessionFactory();\r\n<\/pre>\n<h3>6. Overriding mappings<\/h3>\n<p>Sometimes it is necessary to slightly modify entity mapping. It can be achieved by creating class which implements <i>IAutoMappingOverride<\/i> interface<\/p>\n<pre lang=\"csharp\">\r\npublic class ProjectMapping: IAutoMappingOverride<Project>\r\n{\r\n    public void Override(AutoMapping<Project> mapping)\r\n    {\r\n        mapping.IgnoreProperty(val=>val.SomeIgnoredProperty);\r\n    }\r\n}\r\n<\/pre>\n<p><i>Override<\/i> method gives us access to all actions known from fluent mappings. After creating class map, we have to call function <i>UseOverridesFromAssemblyOf<\/i> in our automapping configuration<\/p>\n<pre lang=\"csharp\">\r\nvar factory = Fluently.Configure().Database(MsSqlConfiguration.MsSql2008.ConnectionString(\"YourConnectionString\"))\r\n                                  .Mappings(val => val.AutoMappings.Add(AutoMap.AssemblyOf<Project>(new DefaultAutomappingConfiguration()).UseOverridesFromAssemblyOf<Project>()\r\n                                  .Conventions.Setup(con =>\r\n                                                                           {\r\n                                                                               con.Add<DefaultTableNameConvention>();\r\n                                                                               con.Add<DefaultPrimaryKeyConvention>();\r\n                                                                               con.Add<DefaultStringLengthConvention>();\r\n                                                                               con.Add<DefaultReferenceConvention>();\r\n                                                                               con.Add<DefaultHasManyConvention>();\r\n                                                                           }))).BuildSessionFactory();\r\n<\/pre>\n<h3>7. It works<\/h3>\n<p>Here just couple of screens from NHibernateProfiler with basic queries<br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoTask.png\" rel=\"attachment wp-att-360\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoTask.png\" alt=\"InsertIntoTask\" width=\"800\"  class=\"aligncenter size-full wp-image-360\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoTask.png 999w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoTask-150x28.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoTask-300x56.png 300w\" sizes=\"(max-width: 999px) 100vw, 999px\" \/><\/a><br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoUser.png\" rel=\"attachment wp-att-361\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoUser.png\" alt=\"InsertIntoUser\" width=\"800\" class=\"aligncenter size-full wp-image-361\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoUser.png 998w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoUser-150x27.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoUser-300x54.png 300w\" sizes=\"(max-width: 998px) 100vw, 998px\" \/><\/a><br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoProject.png\" rel=\"attachment wp-att-359\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoProject.png\" alt=\"InsertIntoProject\" width=\"800\"  class=\"aligncenter size-full wp-image-359\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoProject.png 1004w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoProject-150x28.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/InsertIntoProject-300x56.png 300w\" sizes=\"(max-width: 1004px) 100vw, 1004px\" \/><\/a><br \/>\n<a href=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/SelectFromTask.png\" rel=\"attachment wp-att-362\"><img decoding=\"async\" src=\"http:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/SelectFromTask.png\" alt=\"SelectFromTask\" width=\"800\" class=\"aligncenter size-full wp-image-362\" srcset=\"https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/SelectFromTask.png 997w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/SelectFromTask-150x15.png 150w, https:\/\/tpodolak.com\/blog\/wp-content\/uploads\/2013\/03\/fluent-nhibernate-automappings\/SelectFromTask-300x31.png 300w\" sizes=\"(max-width: 997px) 100vw, 997px\" \/><\/a><br \/>\nSource code for this post can be found <a href=\"https:\/\/github.com\/tpodolak\/Blog\/tree\/master\/NHibernateAutomappings\">here<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. Introduction Writing mappings for models in large application is quite boring task. Fortunatelly, Fluent NHibernate provides possibility for automatic mapping creation &#8211; so called automappings. 2. Creating database and model In order to show you, how to configure automappings in Fluent NHibernate, let&#8217;s create simple database along with model classes. The database structure is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[71,72,3,66],"tags":[214,215,159,209],"class_list":["post-35","post","type-post","status-publish","format-standard","hentry","category-automapper","category-automappings","category-c","category-fluentnhibernate","tag-automapper","tag-automappings","tag-c","tag-fluentnhibernate"],"_links":{"self":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/35","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/comments?post=35"}],"version-history":[{"count":4,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/35\/revisions"}],"predecessor-version":[{"id":541,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/posts\/35\/revisions\/541"}],"wp:attachment":[{"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/media?parent=35"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/categories?post=35"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tpodolak.com\/blog\/wp-json\/wp\/v2\/tags?post=35"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}