NHibernate: связать коллекцию с помощью чего-то другого, чем ПК - PullRequest
0 голосов
/ 02 сентября 2010

Предположим, у меня есть следующие таблицы:

Company           Person                 Address
----------------------------------------------------------------------------
Id (PK)           Id (PK)                Id (PK)
Name              CompanyId (FK)         CompanyId (FK)
                  AccessType             AddressType

Соответствует следующим классам C # .NET:

class Company
{
    int Id;
    List<Person> Employees;
    List<Address> Addresses;
}

class Person
{
    int Id;
    List<Address> CompanyAddresses;
}

class Address
{
    int Id;
    // ...
}

Совершенно легко сопоставить коллекции Person + Address в компаниикласс с использованием NHibernate:

<class name="Company" table="Company">
    <id name="Id" column="Id" />
    <set name="Employees" table="Person">
        <key column="CompanyId" />
        <one-to-many class="Person" />
    </set>
    <set name="Addresses" table="Address">
        <key column="CompanyId" />
        <one-to-many class="Address" />
    </set>
</class>

<class name="Person" table="Person">
    <id name="Id" column="Id" />
</class>

<class name="Address" table="Address">
    <id name="Id" column="Id" />
</class>

Моя проблема в том, как мне сопоставить адреса и с классом Person?Идея состоит в том, что у компаний есть список лиц (сотрудников) и адресов (сайтов), но адреса компании также можно найти у сотрудников компании.(Я знаю, что это немного странно и неортодоксально, но просто подыграйте мне в этом)1014 * ... но объект Person (.NET) НЕ реализует свойство CompanyId для объявления property-ref для хранения воды (и мы предпочитаем, чтобы этого не было).

Как сохранить коллекциюадресов в объекте Person через NHibernate, где Person :: CompanyId = Address :: CompanyId?

Спасибо, ребята.:)

РЕДАКТИРОВАТЬ

На самом деле просто делать карту Person.Company.Addresses, как предложил Диего ниже, но, к сожалению, это не сработаетпоскольку у Компании будет список адресов, у каждого лица, связанного с компанией, будет только подмножество этих адресов.

Я обновил схему таблицы выше.Думайте об этом так, как будто у Person есть AccessType = ENGINEER, тогда в нем будут сохраняться только адреса AddressType = ENGINEERING (в дополнение к CompanyId = CompanyId).

Ответы [ 2 ]

1 голос
/ 02 сентября 2010

Вы не должны пытаться отобразить это напрямую.

Поскольку у человека есть компания (она на столе, я не видел ее в вашем отображении, но она должна быть там), самый простой способ получить адреса - person.Company.Addresses.

Вы можете заключить это в CompanyAddresses свойство, которое просто делегирует Company.Addresses, если хотите.

Обновление : Вы можете легко отфильтровать эти адреса, хотя список будет доступен только для чтения:

public IEnumerable<Address> CompanyAddresses
{
    get { return Company.Addresses.Where(a => a.AddressType == AccessType); }
}
1 голос
/ 02 сентября 2010

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

Таким образом, вы можете добавить столбец PersonId и использовать его в качестве FK для адресов, относящихся к человеку

Address
----------
Id (PK)
PersonID (FK - nullable)
CompanyID (FK - nullable)

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

Address
----------
Id (PK)
Owner (Discriminator, eg either "Person" or "Company")
OwnerID (FK)

Наиболее естественный (из известных мне) способ отображения, который в таком случае представляет собой Таблицу для Иерархии Классов , хотя для этого необходимы подклассы PersonAddress и CompanyAddress.

...