NHibernate - 思维错误?基于Join的子类模型

时间:2009-05-21 13:01:13

标签: nhibernate nhibernate-mapping

我有一个简单的模型类(Part),它从单个表(t_Part)中提取它的信息。

我想要一个名为(ProducedPart)的模型的子类,它仍然使用NHibernate的缓存机制,但只是(Part)在名为“t_PartProduction”的表中具有外键关系的实例。我不需要为第二个表创建一个模型。

我只需要一个只读版本的ProducedPart

我总是可以实现一个Facade / Repository,但我希望设置一个映射,当我在NH中请求“ProducedPart”时,将“t_Part”与“PartProduction”连接起来。

这是使用NH的错误方法吗?

修改

因此,SQL看起来像

SELECT p.* 
FROM t_Part p 
INNER JOIN t_PartProduction pp ON pp.PartID = p.PartID 
WHERE pp.ProductionYear = '2009'

3 个答案:

答案 0 :(得分:1)

此处的关键是同时使用NHibernate Mappings的where定义的mutableclass元素。

使用Fluent NHibernate,这看起来像:

    public Part()
    {
        WithTable("t_Part");

        Id(i => i.Id).ColumnName("PartID");
        Map(m => m.Name).ColumnName("Part");

        SetAttribute("where", "PartID IN ( SELECT pp.PartID FROM t_PartProduction pp WHERE pp.ProductionYear = '2009' ) ");

        ReadOnly();
    }

答案 1 :(得分:1)

不,这完全有可能。在NHibernate文档中查看“每子类表”继承模型。它实际上将它实现为LEFT JOIN,因此当您加载Part时,它会根据是否存在另一行来创建Part或ProducedPart类的实例。您可以在nhibernate.info找到文档。

我不确定你是否可以让ProducedPart只做这个。

我假设:

WHERE pp.ProductionYear = '2009'

您希望子类仅在生产年份为2009年的情况下,即如果t_PartProduction中有不同年份的记录,您希望将此Part视为普通的Part对象,而不是ProducedPart,那么您可以考虑创建数据库中的视图定义是t_PartProduction的过滤版本,然后使您的子类加入此视图而不是基表。

答案 2 :(得分:1)

我相信你要找的是一个连接的子类。在FNH中,它看起来像:

public class PartMap : ClassMap<Part>
{
    public PartMap()
    {
        Id(x => x.Id)

        JoinedSubClass<ProducedPart>("PartID", sub => { 
            sub.Map(x => x.Name); 
            sub.Map(x => x.ProductionYear); 
        });
    }
}

为了让NHibernate缓存结果,你需要映射子类(如果你没有映射它,你将无法让NH首先加载它。)

FNH groups thread引入一些上下文,但它不会显式为只读。在我看来,将事物设为只读对于NHibernate来说并不合适。这可以通过数据库和连接更好地控制(即创建与数据库的连接,该数据库仅对正在访问的表/视图具有SELECT权限)。请参阅my answer之前关于NHibernate中只读会话的​​SO问题,以了解更多关于此事的想法。