Как отобразить интерфейс в nhibernate? - PullRequest
7 голосов
/ 18 февраля 2010

Я использую два класса NiceCustomer & RoughCustomer, которые влияют на интерфейс ICustomer.

ICustomer имеет четыре свойства. Это:

  1. Property Id() As Integer
  2. Property Name() As String
  3. Property IsNiceCustomer() As Boolean
  4. ReadOnly Property AddressFullText() As String

Я не знаю, как сопоставить интерфейс ICustomer с базой данных.

Я получаю такую ​​ошибку во внутреннем исключении.

Ассоциация относится к не отображенному классу: ICustomer

Я использую Fluent и NHibernate.

Ответы [ 3 ]

4 голосов
/ 17 февраля 2014

Вы можете сопоставить напрямую с интерфейсами в NHibernate, подключив EmptyInterceptor на этапе настройки. Задача этого перехватчика - предоставлять реализации для интерфейсов, которые вы определяете в файлах сопоставления.

public class ProxyInterceptor : EmptyInterceptor
{
    public ProxyInterceptor(ITypeHandler typeHandler) {
        // TypeHandler is a custom class that defines all Interface/Poco relationships
        // Should be written to match your system
    }

    // Swaps Interfaces for Implementations
    public override object Instantiate(string clazz, EntityMode entityMode, object id)
    {
        var handler = TypeHandler.GetByInterface(clazz);
        if (handler == null || !handler.Interface.IsInterface) return base.Instantiate(clazz, entityMode, id);
        var poco = handler.Poco;
        if (poco == null) return base.Instantiate(clazz, entityMode, id);

        // Return Poco for Interface
        var instance = FormatterServices.GetUninitializedObject(poco);
        SessionFactory.GetClassMetadata(clazz).SetIdentifier(instance, id, entityMode);

        return instance;
    }

}

После этого все отношения и сопоставления могут быть определены как интерфейсы.

public Parent : IParent {
    public int ID { get; set; }
    public string Name { get; set; }
    public IChild Child { get; set; }
}

public Child : IChild {
    public int ID { get; set; }
    public string Name { get; set; }
}

public class ParentMap : ClassMap<IParent>
{
    public ParentMap()
    {
        Id(x => x.ID).GeneratedBy.Identity().UnsavedValue(0);
        Map(x => x.Name)
    }
}   

...

Этот тип техники хорош, если вы хотите добиться истинного разделения вашего ORM, размещения всех конфигураций / отображений в отдельном проекте и только ссылки на интерфейсы. В этом случае ваш домен не будет загрязнен ORM, и вы сможете заменить его на более позднем этапе, если потребуется.

0 голосов
/ 21 апреля 2010

как ты делаешь запросы?Если вы используете HQL, вам нужно импортировать пространство имен интерфейса с файлом HBM с такой строкой:

<import class="name.space.ICustomer, Customers" />

Если вы используете Criteria, вы просто должны иметь возможность запросить ICustomer, и он вернетоба типа клиентов.

Если вы отображаете класс, в котором есть клиент, с помощью HasMany, HasManyToMany или References, вам необходимо использовать общую форму:

References<NiceCustomer>(f=>f.Customer)

Еслиесли вы хотите, чтобы он справлялся с любым из них, вам нужно сделать их подклассами

Subclassmap<NiceCustomer>

В этом случае я думаю, что вам понадобится базовый класс Customer и использовать его для параметра универсального типа во внешнем классе:

References<Customer>(f=>f.Customer)

Несмотря на это, вам не следует менять модель своего домена, чтобы справиться с этим, у него все равно должен быть ICustomer во внешнем классе.

Я не уверен, что 1.0У RTM есть общая форма, работающая для ссылок, но быстрое сканирование изменений должно показать изменение, которое, я думаю, является добавлением в две строки.

0 голосов
/ 18 февраля 2010

Невозможно отобразить интерфейс в nhibernate. Если ваша цель состоит в том, чтобы иметь возможность запрашивать, используя общий тип для получения клиентов обоих типов, вы можете использовать полиморфный запрос. Просто попросите оба ваших класса реализовать интерфейс и отобразить классы как обычно. Смотрите эту ссылку:

https://www.hibernate.org/hib_docs/nhibernate/html/queryhql.html (раздел 11.6)

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