static void mapper_BeforeMapClass(NHibernate.Mapping.ByCode.IModelInspector modelInspector, System.Type type, NHibernate.Mapping.ByCode.IClassAttributesMapper classCustomizer) { classCustomizer.Cache(cacheMapping => cacheMapping.Usage(NHibernate.Mapping.ByCode.CacheUsage.ReadWrite)); string fullName = type.FullName; // example: Domain.TheProduction+Product string[] fullNameSplit = fullName.Split('+'); string className = fullNameSplit[1]; // Last() skips the other namespace(s) string schemaDomainName = fullNameSplit[0].Split('.').Last(); string schemaName = schemaDomainName.Substring(0, schemaDomainName.Length - "Domain".Length); string sqlServerFullName = schemaName + "." + className; classCustomizer.Table(sqlServerFullName); System.Reflection.MemberInfo mi = type.GetMember(className + "Id", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)[0]; classCustomizer.Id(mi, idMapper => { idMapper.Column(className + "Id"); idMapper.Generator(NHibernate.Mapping.ByCode.Generators.Identity); }); }
void Mapper_BeforeMapClass( NHibernate.Mapping.ByCode.IModelInspector modelInspector, System.Type type, NHibernate.Mapping.ByCode.IClassAttributesMapper classCustomizer ) { if (this.UseCache) { classCustomizer.Cache(cacheMapping => cacheMapping.Usage(NHibernate.Mapping.ByCode.CacheUsage.ReadWrite)); } string fullName = type.FullName; // example: AspNetCoreExample.Ddd.IdentityDomain.ApplicationUser var(schemaName, tableName) = fullName.GetTableMapping(); classCustomizer.Schema(schemaName); classCustomizer.Table(tableName); classCustomizer.Lazy(true); // If this needs to be turned on.. classCustomizer.DynamicUpdate(true); // ..this needs to be turned on too. classCustomizer.SelectBeforeUpdate(true); // As not doing so, could cause inconsistent update: http://stackoverflow.com/questions/13954882/nhibernate-dynamic-update-disadvantages CustomizeIdPrimaryKey(type, classCustomizer, schemaName, tableName); CustomizeEnumPrimaryKey(type, classCustomizer); }
static void mapper_BeforeMapBag( NHibernate.Mapping.ByCode.IModelInspector modelInspector, NHibernate.Mapping.ByCode.PropertyPath member, NHibernate.Mapping.ByCode.IBagPropertiesMapper propertyCustomizer) { /* * class Person * { * IList<Hobby> Hobbies * } * * */ string parentEntity = member.LocalMember.DeclaringType.Name; // this gets the Person string foreignKey = parentEntity + "Id"; propertyCustomizer.Key(keyMapping => keyMapping.Column(foreignKey)); // http://www.ienablemuch.com/2014/10/inverse-cascade-variations-on-nhibernate.html // best persistence approach: Inverse+CascadeAll propertyCustomizer.Inverse(true); propertyCustomizer.Cascade(NHibernate.Mapping.ByCode.Cascade.All); propertyCustomizer.Cache(cacheMapping => cacheMapping.Usage(NHibernate.Mapping.ByCode.CacheUsage.ReadWrite)); }
static void mapper_BeforeMapProperty( NHibernate.Mapping.ByCode.IModelInspector modelInspector, NHibernate.Mapping.ByCode.PropertyPath member, NHibernate.Mapping.ByCode.IPropertyMapper propertyCustomizer) { //string postgresFriendlyName = member.ToColumnName().ToLowercaseNamingConvention(); //propertyCustomizer.Column(postgresFriendlyName); }
static void Mapper_BeforeMapManyToMany( NHibernate.Mapping.ByCode.IModelInspector modelInspector, NHibernate.Mapping.ByCode.PropertyPath propertyPath, NHibernate.Mapping.ByCode.IManyToManyMapper manyToManyMapper ) { System.Type collectionModelType = propertyPath.CollectionElementType(); string childKeyName = propertyPath.CollectionElementType().Name.ToLowercaseNamingConvention() + "_fk"; manyToManyMapper.Column(childKeyName); manyToManyMapper.Lazy(NHibernate.Mapping.ByCode.LazyRelation.Proxy); }
void Mapper_AfterMapProperty( NHibernate.Mapping.ByCode.IModelInspector modelInspector, NHibernate.Mapping.ByCode.PropertyPath propertyPath, NHibernate.Mapping.ByCode.IPropertyMapper propertyMapper ) { dynamic lm = propertyPath.LocalMember; System.Type st = lm.PropertyType; // why NHibernate is hiding PropertyType? thanks to dynamic keyword, nothing can hide from dynamic if (st == typeof(Jsonb)) { propertyMapper.Type(typeof(AspNetCoreExample.Infrastructure.NHibernateInfra.JsonbType), parameters: null); } }
static void Mapper_BeforeMapProperty( NHibernate.Mapping.ByCode.IModelInspector modelInspector, NHibernate.Mapping.ByCode.PropertyPath propertyPath, NHibernate.Mapping.ByCode.IPropertyMapper propertyMapper ) { string postgresFriendlyName = propertyPath.ToColumnName().ToLowercaseNamingConvention(); propertyMapper.Column(postgresFriendlyName); System.Type st = propertyPath.LocalMember.GetPropertyOrFieldType(); // http://www.ienablemuch.com/2018/06/utc-all-things-with-nhibernate-datetime-postgres-timestamptz.html if (st == typeof(System.DateTime) || st == typeof(System.DateTime?)) { propertyMapper.Type <Infrastructure.NHibernateInfra.CustomUtcType>(); } }
static void mapper_BeforeMapManyToOne( NHibernate.Mapping.ByCode.IModelInspector modelInspector, NHibernate.Mapping.ByCode.PropertyPath member, NHibernate.Mapping.ByCode.IManyToOneMapper propertyCustomizer) { /* * * public class Product * { * protected internal int ProductId { get; set; } * * public TheProduction.ProductCategory ProductCategory { get; protected internal set; } * public string ProductName { get; protected internal set; } * } * */ // ProductCategory property name maps to ProductCategoryId column name propertyCustomizer.Column(member.ToColumnName() + "Id"); }
void Mapper_BeforeMapJoinedSubclass( NHibernate.Mapping.ByCode.IModelInspector modelInspector, System.Type type, NHibernate.Mapping.ByCode.IJoinedSubclassAttributesMapper joinedSubclassAttributesMapper) { // not working though joinedSubclassAttributesMapper.Lazy(true); /* * class Animal * { * } * * class Dog : Animal * { * } */ System.Type baseType = type.BaseType; // Animal var(schemaName, tableName) = type.FullName.GetTableMapping(); joinedSubclassAttributesMapper.Schema(schemaName); joinedSubclassAttributesMapper.Table(tableName); joinedSubclassAttributesMapper.Key(k => { // postgresFriendlyName would be lowercase animal string postgresFriendlyName = baseType.Name.ToLowercaseNamingConvention(); k.Column(postgresFriendlyName + "_fk"); k.Unique(true); k.NotNullable(true); // k.OnDelete(NHibernate.Mapping.ByCode.OnDeleteAction.Cascade); }); System.Diagnostics.Debug.WriteLine("Before joined subclass" + type); }
void Mapper_BeforeMapSet( NHibernate.Mapping.ByCode.IModelInspector modelInspector, NHibernate.Mapping.ByCode.PropertyPath propertyPath, NHibernate.Mapping.ByCode.ISetPropertiesMapper setPropertiesCustomizer ) { // this gets the person table. lowercase name in postgres. string parentEntity = propertyPath.LocalMember.DeclaringType.Name.ToLowercaseNamingConvention(); string foreignKey = parentEntity + "_fk"; setPropertiesCustomizer.Key(keyMapping => keyMapping.Column(foreignKey)); // See advantage of Extra Lazy here: http://www.ienablemuch.com/2013/12/pragmatic-ddd.html setPropertiesCustomizer.Lazy(NHibernate.Mapping.ByCode.CollectionLazy.Extra); if (this.UseCache) { setPropertiesCustomizer.Cache( cacheMapping => cacheMapping.Usage(NHibernate.Mapping.ByCode.CacheUsage.ReadWrite) ); } }
static void Mapper_BeforeMapManyToOne( NHibernate.Mapping.ByCode.IModelInspector modelInspector, NHibernate.Mapping.ByCode.PropertyPath propertyPath, NHibernate.Mapping.ByCode.IManyToOneMapper manyToOneMapper ) { /* * * public class Product * { * protected internal int ProductId { get; set; } * * public TheProduction.ProductCategory ProductCategory { get; protected internal set; } * public string ProductName { get; protected internal set; } * } * */ // ProductCategory property name maps to product_category_fk column name string columnName = propertyPath.ToColumnName(); string postgresFriendlyName = columnName.ToLowercaseNamingConvention(); if (!(columnName == "CreatedBy" || columnName == "ModifiedBy")) { postgresFriendlyName = postgresFriendlyName + "_fk"; } manyToOneMapper.Column(postgresFriendlyName); // Looks like we need to use no-proxy, we might encounter ghost object // https://ayende.com/blog/4378/nhibernate-new-feature-no-proxy-associations manyToOneMapper.Lazy(NHibernate.Mapping.ByCode.LazyRelation.Proxy); }
void Mapper_BeforeMapBag( NHibernate.Mapping.ByCode.IModelInspector modelInspector, NHibernate.Mapping.ByCode.PropertyPath propertyPath, NHibernate.Mapping.ByCode.IBagPropertiesMapper bagPropertiesCustomizer ) { /* * class Person * { * IList<Hobby> Hobbies * } * * */ // this gets the person table. lowercase name in postgres. string parentEntity = propertyPath.LocalMember.DeclaringType.Name.ToLowercaseNamingConvention(); string foreignKey = parentEntity + "_fk"; bagPropertiesCustomizer.Key(keyMapping => keyMapping.Column(foreignKey)); // http://www.ienablemuch.com/2014/10/inverse-cascade-variations-on-nhibernate.html // best persistence approach: Inverse+CascadeAll bagPropertiesCustomizer.Inverse(true); bagPropertiesCustomizer.Cascade(NHibernate.Mapping.ByCode.Cascade.All | NHibernate.Mapping.ByCode.Cascade.DeleteOrphans); bagPropertiesCustomizer.Lazy(NHibernate.Mapping.ByCode.CollectionLazy.Extra); if (this.UseCache) { bagPropertiesCustomizer.Cache( cacheMapping => cacheMapping.Usage(NHibernate.Mapping.ByCode.CacheUsage.ReadWrite) ); } }