是否可以使用NHibernate将多个表映射到单个域模型?它基本上是一个 UNION ,如下所示,但我不知道如何在C#中进行域模型和NHibernate的映射。
我基本上有 1个抽象类和 2个具体类。每个具体类都可以映射到数据库中的单个表。
SQL语句:
SELECT *
FROM InCompleOrders
UNION
SELECT *
FROM CompleteOrders
目前我这样做:
C#域模型:
public enum Status
{
InComplete = 1,
Pending = 2,
Complete = 3
}
public abstract class BaseOrder : Entity
{
public string Property1 {get;set;}
public string Property2 {get;set;}
public string Property3 {get;set;}
public Status Status {get;set;}
public string Reference {get;set;} //this is unique
}
public class InCompleteOrder : BaseOrder
{
public override Status Status
{
get { return Status.InComplete; }
}
}
public class Order : BaseOrder
{
public DateTime DeliveredOn {get;set;}
public DateTime PaidOn {get;set;}
}
数据库表:
InCompleOrders table
InCompleOrderId INT PK
Property1 varchar(255) NULL
Property2 varchar(255) NULL
Property3 varchar(255) NULL
CompleteOrders table
CompleteOrderId INT PK
Status INT
Property1 varchar(255) NOT NULL
Property2 varchar(255) NOT NULL
Property3 varchar(255) NOT NULL
DeliveredOn datetime NOT NULL
PaidOn datetime NOT NULL
NHibernate映射:
<class name="Order" table="CompleteOrders">
<id name="Id" column="CompleteOrderId" type="int">
<generator class ="hilo"></generator>
</id>
<property name="DeliveredOn" column="DeliveredOn" not-null="true" type="DateTime" />
<property name="PaidOn" column="PaidOn" not-null="true" type="DateTime" />
<property name="Property1" column="Property1" not-null="true" type="string" />
<property name="Property2" column="Property2" not-null="true" type="string" />
<property name="Property3" column="Property3" not-null="true" type="string" />
</class>
<class name="InCompleteOrder " table="InCompleOrders">
<id name="Id" column="InCompleOrderId" type="int">
<generator class ="hilo"></generator>
</id>
<property name="Property1" column="Property1" not-null="false" type="string" />
<property name="Property2" column="Property2" not-null="false" type="string" />
<property name="Property3" column="Property3" not-null="false" type="string" />
</class>
我想避免做以下事情:
public BaseOrder GetByReference (string reference)
{
BaseOrder bo;
var repoOrder = new Repository<Order>();
bo = repoOrder.FindOne(query);
//query = Restrictions.Eq("Reference", reference)
if (bo == null)
{
var repoInCompOrder = new Repository<InCompleteOrder>();
bo = repoInCompOrder.FindOne(query);
//query = Restrictions.Eq("Reference", reference)
}
return bo;
}
我希望能够做到这样的事情:
public Order GetByReference (string reference)
{
var repoOrder = new Repository<Order>();
var bo = repoOrder.FindOne(query);
//query = Restrictions.Eq("Reference", reference) //reference = "abc"
//and this will generate a SQL similar to:
//
//SELECT CompleteOrderId
// , Status
//FROM CompleteOrders
//WHERE Reference = 'abc'
//
//UNION
//
//SELECT InCompleOrderId
// , 1 AS 'Status'
//FROM InCompleOrders
//WHERE Reference = 'abc'
return bo;
}
答案 0 :(得分:4)
是的,您可以使用许多选项来执行您想要的操作。 Ayende Rahien有一个great demonstration of the options用于表继承和结果表结构。
使用具有抽象BaseOrder作为CompleteOrder和IncompleteOrder父类的类层次结构,联合案例为:
<class name="CompleteOrder" table="CompleteOrders">
<id name="Id">
<generator class="identity"/>
</id>
<property name="Status"/>
</class>
<class name="IncompleteOrder" table="IncompleteOrders">
<id name="Id">
<generator class="identity"/>
</id>
</class>
或
<class name="BaseOrder" abstract="true" table="Orders">
<id name="Id">
<generator class="hilo"/>
</id>
<union-subclass table="CompleteOrders" name="CompleteOrder">
<property name="Status"/>
</union-subclass>
<union-subclass table="IncompleteOrders" name="IncompleteOrder">
</union-subclass>
</class>
也有单独的表,但不使用联合进行查询。
查看article,它可能会有很大帮助。
修改强>
有一条关于不想投的评论,但它现在已经消失了。我不确定它是否被删除或是否是SO问题......
如果BaseOrder.Status是虚拟属性,您应该能够传递BaseOrder而不需要强制转换。您必须维护额外的类层次结构,但您仍然可以一起查询它们,并且在大多数情况下,应用程序的其余部分不需要了解子类。
祝你好运!答案 1 :(得分:-1)
您是否考虑过使用[view][1]
?
您可以按如下方式定义view
:
CREATE VIEW AllOrders AS
SELECT CompleteOrderId
, Status
FROM CompleteOrders
WHERE Reference = 'abc'
UNION
SELECT InCompleOrderId
, 1 AS 'Status'
FROM InCompleOrders
WHERE Reference = 'abc'
从Hibernate(以及可能是NHibernate)的角度来看,AllOrders
只是另一个将域对象映射到的表。
有一点需要注意的是,您将无法对视图执行插入操作(更新可能有效也可能无效,我不确定)。因此,如果您需要执行写入操作,您可能仍需要独立映射到CompleteOrders和InCompleteOrders。
修改:看起来我错误地认为无法将数据插入到视图中 - http://www.google.com/search?q=insertable%20view