Обработка отношения «один ко многим» с типами значений в Fluent NHibernate - PullRequest
3 голосов
/ 27 марта 2011

Я работаю над переносом приложения в NHibernate и использую Fluent NHibernate. Я сталкиваюсь с проблемой сопоставления коллекции типов значений с совокупным корнем.

У меня есть тип значения PhoneNumber, который имеет несколько свойств & mdash; Number, NumberType и Description. В моем домене есть несколько объектов, у которых есть коллекции телефонных номеров.

В базе данных (SQL 2008) эти значения хранятся в разных таблицах. Так что у меня могут быть Customers и CustomerPhoneNumbers, а также Vendors и VendorPhoneNumbers. Таблицы телефонных номеров идентичны, за исключением внешнего ключа, который связывает их с их родителем.

Проблема в том, что я хотел бы использовать простой тип значения PhoneNumber без необходимости создавать типы CustomerPhoneNumber и VendorPhoneNumber, свойства которых связывают их с родительским типом, и я не знаю, как это сделать. добиться этого в NHibernate. Возможно ли это или мне нужно изменить мои доменные объекты, чтобы они более точно соответствовали базовой схеме базы данных?

ОБНОВЛЕНИЕ: немного больше информации
Похоже, у меня проблемы даже с получением основной карты для поиска. Вот упрощенный пример того, что у меня есть:

public class CustomerMap : ClassMap<Customer>
{
    public CustomerMap()
    {
        Table("Customers");

        Id(x => x.Id);
        Map(x => x.Name);
        Component(x => x.Address);
        HasMany(x => x.PhoneNumbers)
            .KeyColumn("CustomerId")
            .Cascade.All()
            .Table("CustomerPhoneNumbers");
    }
}

public class PhoneNumberMap : ClassMap<PhoneNumber>
{
    public PhoneNumberMap()
    {
        Id(x => x.Id);
        Map(x => x.Number, "PhoneNumber");
        Map(x => x.PhoneNumberType);
        Map(x => x.Description);
    }
}

Похоже, что SQL генерируется неправильно. Когда я пытаюсь просмотреть список телефонных номеров клиента, я получаю ошибку ADO, которая показывает, что NHibernate ищет таблицу с именем PhoneNumber.

Кажется, что он не берет часть Table("CustomerPhoneNumbers") и по умолчанию использует таблицу, названную так же, как объект. Однако я не могу указать таблицу в PhoneNumberMap, потому что она будет отличаться в зависимости от того, какой агрегированный корень мы выбираем.

1 Ответ

0 голосов
/ 28 марта 2011

Вы можете сопоставить один объект PhoneNumber нескольким таблицам, используя атрибут сопоставления имени объекта. К сожалению, нет примера кода - я не использую Fluent, поэтому не могу помочь с этим аспектом. Я мог бы опубликовать образцы сопоставления HBM, если это будет полезно.

Entity-name в основном заменяет имя класса по всем направлениям. Когда вы используете имя-сущности, вам также придется изменить сеанс, чтобы он принимал параметр для указания имени сущности всякий раз, когда вы работаете с объектами через сеанс.

Документация здесь:

http://docs.jboss.org/hibernate/core/3.2/reference/en/html/mapping.html#mapping-entityname

РЕДАКТИРОВАТЬ Добавлены образцы HBM.

Это сопоставляет один объект PhoneNumber с несколькими таблицами

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="DomainModel.PhoneNumber, DomainModel"
    table="PhoneNumberVendors" entity-name="PhoneNumberVendor">
    <id name="_id" access="field" column="PhoneNumberId">
        <generator class="assigned"/>
    </id>
    <property name= "...">
    </class>
<class name="DomainModel.PhoneNumber, DomainModel"
    table="PhoneNumberCustomers" entity-name="PhoneNumberCustomer">
    <id name="_id" access="field" column="PhoneNumberId">
        <generator class="assigned"/>
    </id>
    <property name= "...">
    </class>
</hibernate-mapping>

Затем, чтобы вызвать, например, обновление для PhoneNumber, вы изменяете синтаксис сеанса так, чтобы nhibernate знал, какую таблицу использовать:

_session.Update("PhoneNumberCustomer", myCustomerNumber) 

Вам придется выяснить, поддерживает ли Fluent это, и если да, то как это сделать. Если нет, вы всегда можете использовать hbm-файлы для объекта PhoneNumber.

...