2010-02-18 3 views
5

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

ICustomer имеет 4 объекта недвижимости. К ним относятся:

  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 и.

+0

Я не думаю, что вам нужно отобразить любой интерфейс как таковой. Не могли бы вы разместить свои файлы сопоставления? Спасибо –

+0

Спасибо, что ответили Махешем. Но, как сказал Кевин, мы не можем сопоставить интерфейс в nhibernate. Я изменил интерфейс на базовый класс. – Josh

ответ

0

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

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

+0

Я тоже пробовал полиморфный запрос, но он не работает. Все еще были проблемы с этим неотображаемым пользователем интерфейса. Таким образом, теперь он стал базовым классом, который отлично работает. Большое спасибо Кевин. – Josh

+0

«Это вполне приемлемо для того, чтобы названный постоянный класс был интерфейсом. Затем вы объявляете реализации классов этого интерфейса с помощью элемента ». http://knol.google.com/k/fabio-maulo/nhibernate-chapter-5-basic-o-r-mapping/1nr4enxv3dpeq/8# – Neal

+3

Ссылка на этот ответ не работает. Обновите ссылку или добавьте более подробную информацию в свой ответ. –

0

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

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

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

Если вы картирование класса, который имеет клиент на него либо через HasMany, HasManyToMany или литературы, то вам необходимо использовать общий вид:

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

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

Subclassmap<NiceCustomer> 

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

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

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

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

3

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

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, и вы можете затем заменить его на более позднем этапе, если вам нужно.

+0

Можете ли вы добавить пример использования ProxyInterceptor в config? Я только начинаю использовать Fluent Nhibernate и не знаю достаточно, чтобы узнать, где указать прокси-сервер ... –

+0

Мне удалось заставить его работать, но проблема в том, что уровень домена по-прежнему чрезмерно загрязнен ORM-специфические методы - прежде всего сеттеры по свойствам. ORM должен иметь возможность устанавливать значение для каждого поля, в то время как в объекте Domain я НЕ хочу, чтобы можно было изменить поле идентификатора объекта (то же самое со многими другими свойствами только для чтения). –

Смежные вопросы