Эквивалент EF6 MapInheritedProperties() в автоматическом преобразовании fluent-nhibernate

В настоящее время я глубоко погружаюсь в NHibernate и в настоящее время смотрю на нюансы между возможностью автоматического сопоставления и явно выраженными конфигурациями API-интерфейса Fluent NHibernate. У меня есть следующие настройки:

public abstract class AuditableEntity : IAuditableEntity
{
    public virtual DateTime CreateDate { get; set; }

    public virtual DateTime? EditDate { get; set; }
}

public abstract class Entity<TKey> : AuditableEntity where TKey : struct
{
    public virtual TKey Id { get; protected set; }
}

И несколько производных доменных сущностей, которые следуют структуре, аналогичной сущности ниже:

public class Brochure : Base.Entity<Int32>
{
    public Brochure()
    {
        Menus = new HashSet<Menu>();
    }

    public virtual string Title { get; set; }

    public virtual string Description { get; set; }

    public virtual ISet<Menu> Menus { get; protected set; }

    public virtual void AddMenu(Menu menu)
    {
        menu.Brochure = this;
        this.Menus.Add(menu);
    }
}

При использовании явных отображений беглого API, я могу подразделить класс ClassMap и использовать его в качестве базового класса для сопоставления сущностей домена. По сути, это дает те же функциональные возможности, что и EF MapInheritedProperties, например, ниже:

public class AuditMap<TEntity> : ClassMap<TEntity> where TEntity : AuditableEntity
{
    public AuditMap()
    {
        this.Map(x => x.CreateDate);
        this.Map(x => x.EditDate);
    }
}

public class BrochureMap : BaseMaps.AuditMap<Brochure>
{
    public BrochureMap()
    {
        this.Id(x =>     x.Id).Not.Nullable().Column("BrochureId").GeneratedBy.HiLo("9");
        this.Map(x => x.Title).Length(50).Not.Nullable();
        this.Map(x => x.Description).Length(250).Nullable();

        this.HasMany(b => b.Menus).LazyLoad()
                                  .AsSet()
                                  .KeyColumn("BrochureId")
                                  .ForeignKeyConstraintName("BrochureId")
                                  .Cascade.All();
    }
}

Тем не менее, я не смог найти четкого подхода к тому, как этого добиться, используя автоматические API-интерфейсы беглого nhibernate с помощью встроенных соглашений или путем реализации пользовательских соглашений, которые также ограничены в своем наборе функций.

Мои текущие и автоматические конфигурации показаны ниже:

        try
        {
            ISessionFactory sessionFactory =
            Fluently.Configure()
                    .Database(() =>
                    {
                        return MsSqlConfiguration.MsSql2012.ConnectionString(c => c.FromConnectionStringWithKey("QuickSnacksDb"))
                                                           .Dialect<MsSql2012Dialect>()
                                                           .Driver<SqlClientDriver>();
                    })
                    .Mappings(m =>
                    {
                        m.AutoMappings.Add(CustomAutomappings);

                        m.FluentMappings.AddFromAssemblyOf<BrochureMap>()
                                        .Conventions.Setup(c =>
                                        {
                                           c.Add(ForeignKey.EndsWith("Id"));
                                        });
                    })
                    .ExposeConfiguration(cfg =>
                    {
                        cfg.EventListeners.PreInsertEventListeners = new IPreInsertEventListener[] { new AuditingEventListener() };
                        cfg.EventListeners.PreUpdateEventListeners = new IPreUpdateEventListener[] { new AuditingEventListener() };
                    })
                    .BuildSessionFactory();

            return sessionFactory;
        }
        catch(FluentConfigurationException e)
        {

        }

Ниже приведены компоненты, используемые в autopping configuratin api...

private static AutoPersistenceModel CustomAutomappings()
{
     return AutoMap.AssemblyOf<Brochure>(new AutoMappingConfiguration())
                   .Conventions.Setup(c =>
                   {
                        c.Add<TableNameConvention>();
                   })
                   .IgnoreBase(typeof(Entity<>))
                   .IncludeBase<AuditableEntity>();
 }

public class TableNameConvention : IClassConvention
{
    public void Apply(IClassInstance instance)
    {
        instance.Table("[dbo].[" + instance.EntityType.Name + "s]");
    }
}

public class AutoMappingConfiguration : DefaultAutomappingConfiguration
{
    public override bool ShouldMap(Type type)
    {
        string typeNamespace = type.Namespace;

        bool mapType = typeNamespace == "QuickSnacks.Data.NHibernate.Entities" || typeNamespace == "QuickSnacks.Data.NHibernate.Entities.Components";

        return mapType;
    }

    public override bool IsComponent(Type type)
    {
        bool mapComponent = type == typeof(AuditInfo);

        return mapComponent;
    }
}

Я понимаю, что это незначительная деталь с точки зрения поддержки аудита, но это позволило мне задаться вопросом о том, в какой степени я смог перехватить конвейер отображения и добавить / переопределить свойства либо базового класса, либо производных подклассов.

Кроме того, учитывая возраст и зрелость nhibernate, многие ссылки (в основном блоги и статьи), с которыми я сталкивался, были разбросаны, ограничены в объеме или просто устарели. Было бы удобно и полезно иметь всеобъемлющий пересмотр nhibernate и связанных с ним проектов на платформе, такой как Read the Docs, но при этом полностью осознавать, что это само по себе было бы достаточно.

Будем весьма благодарны за любые советы, ссылки или указатели по использованию API-интерфейсов Fluent-Nhibernate в продвинутых сценариях.

0 ответов

Другие вопросы по тегам