我有一个简单的模型类(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'
答案 0 :(得分:1)
不,这完全有可能。在NHibernate文档中查看“每子类表”继承模型。它实际上将它实现为LEFT JOIN,因此当您加载Part时,它会根据是否存在另一行来创建Part或ProducedPart类的实例。您可以在nhibernate.info找到文档。
我不确定你是否可以让ProducedPart只做这个。
我假设:
WHERE pp.ProductionYear = '2009'
您希望子类仅在生产年份为2009年的情况下,即如果t_PartProduction中有不同年份的记录,您希望将此Part视为普通的Part对象,而不是ProducedPart,那么您可以考虑创建数据库中的视图定义是t_PartProduction的过滤版本,然后使您的子类加入此视图而不是基表。
答案 1 :(得分: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问题,以了解更多关于此事的想法。
答案 2 :(得分:1)
此处的关键是同时使用NHibernate Mappings的where
定义的mutable
和class
元素。
使用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();
}