首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NHibernate:通过PK以外的东西链接集合

NHibernate:通过PK以外的东西链接集合
EN

Stack Overflow用户
提问于 2010-09-02 04:32:13
回答 2查看 151关注 0票数 0

假设我有以下表格:

代码语言:javascript
复制
Company           Person                 Address
----------------------------------------------------------------------------
Id (PK)           Id (PK)                Id (PK)
Name              CompanyId (FK)         CompanyId (FK)
                  AccessType             AddressType

对应于以下C#.NET类:

代码语言:javascript
复制
class Company
{
    int Id;
    List<Person> Employees;
    List<Address> Addresses;
}

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

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

使用NHibernate映射Company类上的Person + Address集合是非常容易的:

代码语言:javascript
复制
<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类中?这个想法是,公司有一个人员(雇员)和地址(网站)的名单,但公司地址也可以从公司的员工中查找。(我知道,有点奇怪和不正统,但在这件事上跟我一起玩就行了)。

通常,我可以在Person类地图上定义如下所示的内容:

代码语言:javascript
复制
<set name="CompanyAddresses" table="Address">
    <key column="CompanyId" property-ref="CompanyId" />
</set>

..。但是Person (.NET)对象没有为property-ref声明实现一个CompanyId属性来容纳(我们希望它不要)。

如何通过NHibernate在Person对象中持久化地址集合,其中Person::CompanyId = Address::CompanyId?

谢谢你们。:)

编辑

实际上,像迭戈下面所建议的那样,做一个Person.Company.Addresses映射是头等大事,但遗憾的是,这并不能完全奏效,因为虽然一家公司会有一个地址列表,但每个与公司链接的人只会拥有这些地址的一个子集。

我已经更新了上面的表模式。想象一下,如果一个人拥有AccessType = ENGINEER,那么只有AddressType =工程地址将被持久化(除了CompanyId = CompanyId)。

EN

回答 2

Stack Overflow用户

发布于 2010-09-02 07:07:34

如果要为某个人存储地址,我认为您需要在address表中找到链接到person表的链接。

因此,您可以添加一个PersonId列,并将其用作与某人相关的地址的FK。

代码语言:javascript
复制
Address
----------
Id (PK)
PersonID (FK - nullable)
CompanyID (FK - nullable)

或者您可以有一个区分器列,在这种情况下,您的Address表看起来类似于:

代码语言:javascript
复制
Address
----------
Id (PK)
Owner (Discriminator, eg either "Person" or "Company")
OwnerID (FK)

最自然的映射方式(据我所知)是作为每个类层次结构的表,尽管这涉及到PersonAddress和CompanyAddress子类。

票数 1
EN

Stack Overflow用户

发布于 2010-09-02 12:32:26

你不应该试图直接映射它。

由于一个人有一个公司(它在桌子上,我没有在您的映射中看到它,但它应该在那里),获得地址的最简单的方法是person.Company.Addresses

您可以将其包装在一个CompanyAddresses属性中,如果需要,该属性只会委托给Company.Addresses

Update:您可以轻松地过滤这些地址,尽管列表将是只读的:

代码语言:javascript
复制
public IEnumerable<Address> CompanyAddresses
{
    get { return Company.Addresses.Where(a => a.AddressType == AccessType); }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3623837

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档