[英]Subclass table mapping in nHibernate
Firstly, sorry about the wall of text. 首先,对文本墙感到抱歉。
I have the following schema. 我有以下架构。 Note that
User_Contact
may contain a null in ContactID
. 请注意,
User_Contact
ContactID
可以包含null。
At the class level it is then implemented in the following way 然后在类级别上以以下方式实现
public abstract class User : EntityBase<Guid>, IAggregateRoot
{
public User()
{
}
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
protected abstract override void Validate();
}
public class SiteUser : User
{
public SiteUser() { }
public virtual Guid ApplicationId { get; set; }
public virtual string UserName { get; set; }
public virtual string LoweredUserName { get; set; }
public virtual string MobileAlias { get; set; }
public virtual bool IsAnonymous { get; set; }
public virtual DateTime LastActivityDate { get; set; }
protected override void Validate()
{
if (this.ApplicationId == Guid.Empty)
base.AddBrokenRule(UserBusinessRules.ApplicationIdRequired);
if (this.UserName.IsNullOrEmpty())
base.AddBrokenRule(UserBusinessRules.UserNameRequired);
if (this.LoweredUserName.IsNullOrEmpty())
base.AddBrokenRule(UserBusinessRules.LoweredUserNameRequired);
if (this.LastActivityDate == DateTime.MinValue)
base.AddBrokenRule(UserBusinessRules.LastActivityDateRequired);
}
}
public class SiteContact : SiteUser
{
public SiteContact()
{
}
public virtual int ExternalID { get; set; }
//All the rest...
protected override void Validate()
{
//validate
}
}
So basically the idea is that every single SiteContact
is a SiteUser
but not every SiteUser
is a SiteContact
. 因此,基本上的想法是,每个单独的
SiteContact
都是一个SiteUser
但不是每个SiteUser
都是一个SiteContact
。
Where I have gotten completely stuck is how on earth to map this relationship in nHibernate. 我完全陷入困境的是如何在nHibernate中映射这种关系。 I seem to be able to retrieve a
SiteUser
but unable to retrieve a SiteContact
and it is clear why. 我似乎能够检索到
SiteUser
但无法检索到SiteContact
,这很清楚。 The mapping that I have implemented results in the following sql being executed. 我实现的映射导致执行以下sql。
SELECT this_.userid AS UserId18_0_,
this_.firstname AS FirstName18_0_,
this_.lastname AS LastName18_0_,
//Blah blah.....
FROM user_contact this_
INNER JOIN contact this_1_
ON this_.userid = this_1_.contactid //Here is the error this should be ContactID = ContactID
INNER JOIN aspnet_users this_2_
ON this_.userid = this_2_.userid
WHERE ( CASE
WHEN this_.contactid IS NOT NULL THEN 1
ELSE 0
END ) = '1'
But I can't for the life of me work out how to fix this problem in my hbm mapping file. 但是我无法终生解决如何在hbm映射文件中解决此问题。 Here is the file with some fields omitted for simplicity.
为了简单起见,这里是省略了一些字段的文件。
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="MyProject.Namespaces.Model.Entities" assembly="MyProject.Namespaces.Model">
<class name="User" table="User_Contact" lazy="true" abstract="true">
<id name="ID" column="UserId" type="guid">
<generator class="guid" />
</id>
<discriminator column="ContactID" formula="(CASE WHEN ContactID IS NOT NULL THEN 1 ELSE 0 END)" />
<property name="FirstName">
<column name="FirstName" sql-type="nvarchar(500)" not-null="true" />
</property>
<property name="LastName">
<column name="LastName" sql-type="nvarchar(500)" not-null="true" />
</property>
<subclass name="SiteContact" discriminator-value="1">
<join table="Contact">
<key column="ContactID" /> //I assume the problem is here. I have tried adding foreign-key="ContactID" to no success
<property name="ExternalID" insert="false" update="false">
<column name="ExternalID" sql-type="int" not-null="true" />
</property>
//The rest of the mapped columns
</join>
<join table="aspnet_Users">
<key column="UserId" />
<property name="ApplicationId">
<column name="ApplicationId" sql-type="guid" not-null="true" />
</property>
<property name="UserName">
<column name="UserName" sql-type="nvarchar(256)" not-null="true" />
</property>
<property name="LoweredUserName">
<column name="LoweredUserName" sql-type="nvarchar(256)" not-null="true" />
</property>
<property name="MobileAlias">
<column name="MobileAlias" sql-type="nvarchar(16)" not-null="false" />
</property>
<property name="IsAnonymous">
<column name="IsAnonymous" sql-type="bit" not-null="true" />
</property>
<property name="LastActivityDate">
<column name="LastActivityDate" sql-type="datetime" not-null="true" />
</property>
</join>
</subclass>
<subclass name="SiteUser" discriminator-value="0">
<join table="aspnet_Users">
<key column="UserId" />
//blah blah blah
</join>
</subclass>
</class>
</hibernate-mapping>
Hopefully someone could please tell me if I am even on the right track about this mapping and perhaps provide some guidance? 希望有人可以告诉我我是否在有关此映射的正确方法上,也许能提供一些指导?
This seems like a pretty convoluted way of mapping it. 这似乎是一种相当复杂的映射方式。 I'm not sure what benefits you're hoping to achieve from using inheritence in this situation, and I would suggest using composition instead (ie. having a class per table and mapping the relationships).
我不确定在这种情况下使用继承会带来什么好处,我建议改用合成(即每个表都有一个类并映射关系)。
Having said that, you presumably have your reasons, so I would suggest the following to achieve what I think you want: 话虽这么说,您大概有自己的理由,所以我建议采取以下措施来实现我认为的目标:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.