假设我有一个名为Pet的基类和两个继承Pet的子类Cat和Dog。
我只是将这些表映射到三个表Pet,Cat和Dog,其中Pet表包含基类属性,Cat和Dog表包含Pet表的外键以及特定于cat或dog的任何其他属性。一个连接的子类策略。
现在,使用NHibernate和ICriteria,我如何获得所有不同宠物的列表作为Pet对象,而不是Cat或Dog对象 - 只是普通的宠物对象,而不与其他对象进行任何连接表?我只对Pet中包含的信息感兴趣。
答案 0 :(得分:1)
我刚做了类似的事情,发现Ayende的这个blog post非常有帮助!我使用了连接子类方法,它很好地支持查询基类。
然而,为了在没有加入的情况下找到“只有宠物”,我认为您需要每个类的表层次结构方法。或者,您可以使用table-per-subclass并在子类上执行左连接,并将其限制为在任何左连接上没有匹配的行。
答案 1 :(得分:0)
嗯,选择'作为宠物'我会认为带回所有物体(不仅仅是没有分类的宠物)。我不知道干净的方式,但我不是NH专家。
也许您可以直接查询父表中的discriminator列?虽然您可能需要转发到自定义SQL查询而不是HQL或ICriteria。
答案 2 :(得分:0)
这似乎工作正常:
我创建了一个视图,该视图选中了 Pet 表中的所有列。然后我创建了一个我映射到视图的简单DTO类。之后,可以使用ICriteria。
可能不是最漂亮或最干净的解决方案,但与动态查询字符串一起使用起来肯定更容易。
答案 3 :(得分:0)
我不相信您可以使用Criteria API执行此操作。但是,您可以使用HQL执行此操作:
var hql = @"from Pet p where p.class = Pet";
答案 4 :(得分:0)
为什么不为“PetsOnly”创建一个新地图,并删除您的鉴别器和其他非必填字段?我认为克里斯托弗上面也是同样的事情;仍然应该给你完整的插入更新和删除选择支持。宠物只是Pet
......
答案 5 :(得分:0)
对于许多情况都足够好:将属性投影到对象本身。
请谨慎使用,因为在感觉不正确的情况下,对象被破坏
var propsToSelect = Projections.ProjectionList();
foreach (var prop in sessionfactory.GetClassMetadata(typeof(Pet)).PropertyNames)
{
propsToSelect.Add(Projections.Property(prop.Name), prop.Name);
}
var results = session.CreateCriteria<Pet>()
.SetProjection(propsToSelect)
.SetResultTransformer(Transformers.AliasToBean<Pet>())
.List<Pet>();