Свободный nhibernate: Как мне сопоставить сущность со свойством, тип которого является интерфейсом? - PullRequest
3 голосов
/ 11 мая 2009

У меня есть такой объект, как:

public class Employee
{
    public int ID { get; set; }
    public IAccountManager AccountManager { get; set; }
    ...
}

У меня также есть отображение, определенное для «DefaultAccountManager» - конкретной реализации IAccountManager. При отображении вышеупомянутой сущности «Сотрудник», как я могу сказать NHibernate о сохранении / загрузке свойства AccountManager с помощью сопоставления, определенного в «DefaultAccountManager»?

Edit: На самом деле, если бы я мог настроить отображение для IAccountManager так, чтобы NHibernate мог просто определить, какой исполнитель загрузить / сохранить, это было бы еще лучше. Я бы предпочел не нарушать полиморфизм, заставляя всех разработчиков использовать одно и то же отображение.

Ответы [ 3 ]

4 голосов
/ 09 сентября 2009

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

  • Создайте таблицу для каждой реализации IAccountManager, в которой есть сопоставления.
  • Убедитесь, что ваша БД настроена на использование алгоритма HiLo ID.
  • Используйте объединение подклассов в ваших отображениях

Union-подклассы будут выглядеть примерно так:

<class name="IAccountManager" abstract="true">
  <id name="ID" column="ID" type="Int32">
    <generator class="hilo"/>
  </id>
  <union-subclass name="DefaultAccountManager" table="DefaultAccountManager"
      proxy="IAccountManager">
    <property name="FirstName" type="String"/>
    <property name="LastName" type="String"/>
  </union-subclass>
  ... more implementations
</class>

Обратите внимание на атрибут "name" в union-subclass. Это должно быть уникальным (и соответствовать) каждой реализации IAccountManager.

Кроме того, идентификатор, вместо того, чтобы быть уникальным для каждой таблицы, будет уникальным для всех IAccountManager (используя hilo).

Когда NHibernate видит сущность IAccountManager, он использует конкретный тип экземпляра и определения union-subclass для определения правильной таблицы.

Надеюсь, это поможет!

1 голос
/ 23 ноября 2009

Просто подумал, что поделюсь тем, как мне удалось добиться этого, используя Fluent NHibernate, а не файлы hbm.

Этот метод немного хакерский, но хаки изолируются и легко удаляются, когда Fluent NH получает надлежащую поддержку для Union-Subclass.

Чтобы использовать ваш пример, контекст моего сценария таков: класс Employee находится в одном проекте со свойством AccountManager, указанным в качестве интерфейса, поскольку конкретный AccountManager находится в другом проекте, который мы не хотим создавать. зависимость от.

Сначала я создаю класс «Помощник», который выполняет большую часть сопоставления сотрудников и выглядит следующим образом.

public abstract class EmployeeMapperBase
{
    protected abstract Type GetAccountManagerType();

    public void DoMapping(ClassMap<Employee> classMap)
    {
        classMap.Id(x => x.Id);

        classMap.Maps(..... etc....

        classMap.References(x => x.AccountManager)
            .Class(GetAccountManagerType());
    }
}

Далее, в проекте с конкретным классом AccountManager я завершаю отображение:

public class EmployeeClassMap : ClassMap<Employee>
{
    public EmployeeClassMap
    {
        new ConcreteEmployeeMapper().DoMapping(this);
    }

    private class ConcreteEmployeeMapper : EmployeeMapperBase
    {
        public override Type GetAccountManagerType()
        {
            return typeof(DefaultAccountManager);
        }
    }
}
0 голосов
/ 12 мая 2009

Если вам нужен полиморфизм, потому что функциональность реализации IAccountManager может иметь разные функции, вы можете посмотреть на дискриминаторы и использовать базовый класс вместо интерфейса.

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

...