NHibernate:通过 PK 以外的方式链接集合
假设我有下表:
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;
// ...
}
使用 NHibernate 将 Person + Address 集合映射到 Company 类上非常容易:
<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>
我的问题是,如何将 Addresses 也映射到 Person 类中?这个想法是,公司有一个人员(员工)和地址(站点)列表,但公司地址也可以从公司的员工中查找。 (我知道这有点奇怪和非正统,但请跟我一起玩吧)。
通常,我可以通过在 Person 类映射上定义如下所示的内容来实现此目的:
<set name="CompanyAddresses" table="Address">
<key column="CompanyId" property-ref="CompanyId" />
</set>
...但是 Person (.NET) 对象没有实现 CompanyId 属性来使 property-ref
声明保持有效(我们宁愿不这样做)。
如何通过 NHibernate 在 Person 对象中保存地址集合,其中 Person::CompanyId = Address::CompanyId?
谢谢你们。 :)
编辑
实际上,像下面迭戈建议的那样进行 Person.Company.Addresses
映射是最重要的,但遗憾的是,这并不完全有效,因为虽然公司将有一个地址列表,链接到公司的每个人将仅拥有这些地址的子集。
我已经更新了上面的表架构。可以想象,如果一个 Person 的 AccessType = ENGINEER,那么只有 AddressType = ENGINEERING 地址将保留在其中(除了 CompanyId = CompanyId 之外)。
Suppose I have the following tables:
Company Person Address
----------------------------------------------------------------------------
Id (PK) Id (PK) Id (PK)
Name CompanyId (FK) CompanyId (FK)
AccessType AddressType
Corresponding to the following C#.NET classes:
class Company
{
int Id;
List<Person> Employees;
List<Address> Addresses;
}
class Person
{
int Id;
List<Address> CompanyAddresses;
}
class Address
{
int Id;
// ...
}
It's perfectly easy to map the Person + Address collections on the Company class using 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>
My problem is, how do I map the Addresses into the Person class as well? The idea is that, Companies have a list of Persons (employees) and Addresses (sites), but the Company addresses can also be looked up from the company's employees. (A bit weird and unorthodox, I know, but just play along with me on this).
Normally, I could do this by defining something like below on the Person class map:
<set name="CompanyAddresses" table="Address">
<key column="CompanyId" property-ref="CompanyId" />
</set>
... but the Person (.NET) object does NOT implement a CompanyId property for the property-ref
declaration to hold water (and we prefer for it not to).
How would I persist a collection of Addresses in the Person object via NHibernate, where Person::CompanyId = Address::CompanyId?
Thanks guys. :)
EDIT
It's actually top-of-head to just do a Person.Company.Addresses
mapping like Diego suggested below, but sadly, that won't exactly work because while a Company would have a list of Addresses, each Person linked to a Company will only have a subset of those Addresses.
I've updated the table schema above. Think of it as like if a Person has AccessType = ENGINEER, then only AddressType = ENGINEERING Addresses will be persisted in it (in addition to CompanyId = CompanyId).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您要存储某人的地址,我认为您需要在地址表中添加一些内容来链接回人员表。
因此,您可以添加一个 PersonId 列,并将其用作与某个人相关的地址的 FK
或者您可以有一个鉴别器列,在这种情况下,您的地址表将类似于:
最自然的方式(我'我知道)映射然后是作为每个类层次结构的表,尽管这涉及拥有 PersonAddress 和 CompanyAddress 子类。
If you're going to store an address for a person I think you'd need something in the Address table to link back to the Person table.
So, you could either add a PersonId column, and use that as the FK for addresses which relate to a person
Or you could have a discriminator column, in which case your Address table would look something like:
The most natural way (that I'm aware of) of mapping that is then as a Table per Class Hierarchy, though that involves having PersonAddress and CompanyAddress subclasses.
您不应该尝试直接映射它。
由于一个人有一个公司(它在表格上,我没有在您的映射中看到它,但它应该在那里),获取地址的最简单方法是
person.Company.Addresses
。如果需要,您可以将其包装在
CompanyAddresses
属性中,该属性仅委托给Company.Addresses
。更新:您可以轻松过滤这些地址,尽管该列表是只读的:
You shouldn't try to map it directly.
Since a Person has a Company (it's on the table, I didn't see it in your mapping, but it should be there), the easiest way to get the addresses is
person.Company.Addresses
.You can wrap that in a
CompanyAddresses
property that just delegates toCompany.Addresses
if you want.Update: You can easily filter those addresses, although the list will be readonly: