FluentNHibernate AutoPersistenceModel со ссылками на интерфейс - PullRequest
1 голос
/ 13 декабря 2010

Я пробую FluentNHibernate AutoPersistenceModel в первый раз. Было очень просто заставить работать базовый пример, но у меня возникла проблема приведения его в соответствие с тем, как я работаю. Обычно я работаю с интерфейсами, чтобы все мои сущности реализовывали интерфейс и ссылались на все связанные сущности по их интерфейсу, а не по их конкретному типу. Даны следующие классы:

public Interface IFoo { }

public Interface IBar { IFoo Foo { get; set; } }

public Class Foo : IFoo { }

public Class Bar : IBar
{
     public IFoo Foo { get; set; }
}

У меня будет следующее отображение:

public class BarMapping : ClassMap<Bar>
{
    public AnswerMapping()
    {
        References<Foo>( x => x.Foo ).Column( "FooId" ).Cascade.None();
    }
}

Как бы я достиг того же с AutoPersistenceModel? Я кратко ознакомился с Конвенциями и компоновщиком ReferenceConvention, но без какой-либо документации или примеров я колебался.

EDIT

Теперь я включил это вместе с моим другим сообщением SO о сопоставлении коллекций с интерфейсами в сообщение в блоге: http://bronumski.blogspot.com/2011/01/making-fluent-nhibernate-automapper.html

1 Ответ

1 голос
/ 13 декабря 2010

После небольшого копания я нашел решение. Существует интерфейс IReferenceConvention, который, как я видел, использовался в других примерах, но не охватывает этот сценарий. Благодаря реализации интерфейса и выполнению пользовательского соглашения я смог добиться того же с AutoPersistenceModel, что и с ClassMap.

public class ReferenceConvention : IReferenceConvention
{
    public void Apply(IManyToOneInstance instance)
    {
        Type instanceType = instance.Class.GetUnderlyingSystemType();
        if (instanceType == typeof(IFoo))
        {
            instance.CustomClass<Foo>();
        }

        instance.Cascade.All();
    }
}

Более общий подход может быть:

public class ReferenceConvention : IReferenceConvention
{
    public void Apply(IManyToOneInstance instance)
    {
        Type instanceType = instance.Class.GetUnderlyingSystemType();

        if (instanceType.IsInterface)
        {
            // Assuming that the type starts with an I get the name of the concrete class
            string className = instanceType.Name.Substring( 1 );

            instance.CustomClass(instanceType.Assembly.GetType(
                instanceType.FullName.Replace( instanceType.Name, className )));
        }

        instance.Cascade.All();
    }
}

Существует также ReferenceConventionBuilder, который я еще не рассматривал, но это может быть более чистым решением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...