public override Configuration Map(Configuration cfg)
        {
            ConventionModelMapper mapper = new ConventionModelMapper();

            mapper.IsEntity((x, y) => this.IsEntity(x, y, this.EntitiesAssemblyName));
            mapper.IsRootEntity((x, y) => this.IsRootEntity(x, y, this.EntitiesAssemblyName));
            mapper.IsOneToMany((x, y) => this.IsOneToMany(x, y));
            mapper.IsManyToOne((x, y) => this.IsManyToOne(x, y));
            mapper.IsManyToMany((x, y) => this.IsManyToMany(x, y));
            mapper.IsBag((x, y) => this.IsBag(x, y));
            mapper.IsSet((x, y) => this.IsSet(x, y));
            mapper.IsProperty((x, y) => this.IsProperty(x, y));
            mapper.IsPersistentProperty((x, y) => this.IsPersistentProperty(x, y));
            mapper.BeforeMapClass      += this.BeforeMapClass;
            mapper.BeforeMapProperty   += this.BeforeMapProperty;
            mapper.BeforeMapSet        += this.BeforeMapSet;
            mapper.BeforeMapOneToMany  += this.BeforeMapOneToMany;
            mapper.BeforeMapManyToOne  += this.BeforeMapManyToOne;
            mapper.BeforeMapManyToMany += BeforeMapManyToMany;

            HbmMapping mappings = mapper.CompileMappingFor(Assembly.Load(this.EntitiesAssemblyName).GetExportedTypes());

            cfg.AddMapping(mappings);

            return(cfg);
        }
Example #2
0
        public void ApplyTo(ConventionModelMapper modelMapper)
        {
            modelMapper.BeforeMapClass += (inspector, type, customizer) =>
            {
                customizer.Table($"`{type.Name}`");

                customizer.Id(mapper =>
                {
                    mapper.Generator(Generators.Identity);
                    mapper.Access(Accessor.Field);
                });

                customizer.Version(type.GetProperty(nameof(Entity.Version)), mapper => { });
            };

            modelMapper.BeforeMapManyToOne += (inspector, member, customizer) =>
            {
                customizer.Column(mapper => mapper.Name(member.ToColumnName() + "Id"));
                customizer.ForeignKey(
                    $"FK_{member.GetContainerEntity(inspector).Name.ToUpper()}_{member.LocalMember.Name.ToUpper()}");
                customizer.Index(
                    ($"IDX_{member.GetContainerEntity(inspector).Name.ToUpper()}_{member.LocalMember.Name.ToUpper()}"));

                if (member.LocalMember.GetPropertyOrFieldType().IsSubclassOf(typeof(AggregateRoot)) == false)
                {
                    customizer.Cascade(Cascade.Persist);
                }

                var uniqueAttribute = member.LocalMember.GetCustomAttribute <UniqueAttribute>();
                if (uniqueAttribute != null)
                {
                    if (string.IsNullOrEmpty(uniqueAttribute.Key) == false)
                    {
                        customizer.UniqueKey($"UQ_{uniqueAttribute.Key}");
                    }
                    else
                    {
                        customizer.Unique(true);
                    }
                }
            };

            modelMapper.BeforeMapManyToMany += (inspector, member, customizer) =>
            {
                customizer.Column(mapper => mapper.Name(member.ToColumnName().TrimEnd('s') + "Id"));
                customizer.ForeignKey(
                    $"FK_{member.GetContainerEntity(inspector).Name.ToUpper()}_{member.LocalMember.Name.ToUpper()}_{member.ToColumnName().TrimEnd('s') + "Id"}");
            };

            modelMapper.BeforeMapProperty += (inspector, member, customizer) =>
            {
                var memberType      = member.LocalMember.GetPropertyOrFieldType();
                var uniqueAttribute = member.LocalMember.GetCustomAttribute <UniqueAttribute>();
                if (uniqueAttribute != null)
                {
                    if (string.IsNullOrEmpty(uniqueAttribute.Key) == false)
                    {
                        customizer.UniqueKey($"UQ_{uniqueAttribute.Key}");
                    }
                    else
                    {
                        customizer.Unique(true);
                    }
                }

                var indexAttribute = member.LocalMember.GetCustomAttribute <IndexAttribute>();
                if (indexAttribute != null)
                {
                    customizer.Index(
                        $"IDX_{member.GetContainerEntity(inspector).Name.ToUpper()}_{member.ToColumnName().ToUpper()}");
                }

                if (this.userTypes.TryGetValue(memberType, out var userType))
                {
                    customizer.Type(userType, null);
                }

                if (memberType == typeof(byte[]))
                {
                    customizer.Length(int.MaxValue);
                }
            };

            modelMapper.BeforeMapJoinedSubclass += (inspector, type, customizer) =>
            {
                customizer.Key(mapper => mapper.Column(columnMapper => columnMapper.Name($"{type.BaseType.Name}Id")));
                customizer.Key(mapper => mapper.ForeignKey($"FK_{type.Name.ToUpper()}_{type.BaseType.Name.ToUpper()}"));
            };

            modelMapper.BeforeMapBag  += OnBeforeMapCollection;
            modelMapper.BeforeMapList += OnBeforeMapCollection;
            modelMapper.BeforeMapList += (inspector, member, customizer) =>
            {
                customizer.Inverse(false);
                customizer.Index(m => m.Column("`Index`"));
            };
            modelMapper.BeforeMapSet   += OnBeforeMapCollection;
            modelMapper.BeforeMapIdBag += OnBeforeMapCollection;

            modelMapper.BeforeMapElement += (inspector, member, customizer) => { customizer.Column("Value"); };

            modelMapper.IsEntity((type, b) => typeof(Entity).IsAssignableFrom(type) && type != typeof(AggregateRoot));
            modelMapper.IsRootEntity((type, b) =>
                                     type.BaseType == typeof(Entity) || type.BaseType == typeof(AggregateRoot));
            modelMapper.IsVersion((property, b) => property.Name == nameof(Entity.Version));
            modelMapper.IsProperty((info, declared) => declared || this.userTypes.ContainsKey(info.GetPropertyOrFieldType()));
            modelMapper.IsOneToMany((memberInfo, declared) =>
            {
                if (declared)
                {
                    return(true);
                }

                var collectionType = memberInfo.GetPropertyOrFieldType();

                return(collectionType.IsEnumerableOf <Entity>() &&
                       collectionType.IsEnumerableOf <AggregateRoot>() == false);
            });

            modelMapper.IsManyToMany((memberInfo, declared) =>
                                     declared || memberInfo.GetPropertyOrFieldType().IsEnumerableOf <AggregateRoot>());
            modelMapper.IsList((info, declared) =>
            {
                if (declared)
                {
                    return(true);
                }

                var backingField = info.DeclaringType.GetField(info.Name,
                                                               BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase);

                var propertyType  = backingField?.GetPropertyOrFieldType() ?? info.GetPropertyOrFieldType();
                var isGenericList = propertyType.IsGenericType &&
                                    propertyType.GetGenericTypeDefinition() == typeof(IList <>);
                return(isGenericList);
            });
        }