如何使用NHibernate ICriteria检索没有联接的基类对象列表?

如何使用NHibernate ICriteria检索没有联接的基类对象列表?,nhibernate,icriteria,Nhibernate,Icriteria,假设我有一个名为Pet的基类和继承Pet的两个子类Cat和Dog 我只是将它们映射到三个表Pet、Cat和Dog,其中Pet表包含基类属性,Cat和Dog表包含Pet表的外键以及特定于Cat或Dog的任何其他属性。连接子类策略 现在,使用NHibernate和ICriteria,我如何获得所有不同宠物作为宠物对象的列表,不是猫或狗对象-只是普通宠物对象,而不与其他表进行任何连接?我只对Pet中包含的信息感兴趣。嗯,选择“作为宠物”我认为会带回所有对象(不仅仅是未子类化的宠物)。我不知道有什么干净

假设我有一个名为Pet的基类和继承Pet的两个子类Cat和Dog

我只是将它们映射到三个表Pet、Cat和Dog,其中Pet表包含基类属性,Cat和Dog表包含Pet表的外键以及特定于Cat或Dog的任何其他属性。连接子类策略


现在,使用NHibernate和ICriteria,我如何获得所有不同宠物作为宠物对象的列表,不是猫或狗对象-只是普通宠物对象,而不与其他表进行任何连接?我只对Pet中包含的信息感兴趣。

嗯,选择“作为宠物”我认为会带回所有对象(不仅仅是未子类化的宠物)。我不知道有什么干净的方法,但我不是NH专家


也许您可以直接查询父表中的鉴别器列?尽管您可能必须响应自定义SQL查询,而不是HQL或ICriteria。

嗯,选择“作为宠物”我认为会带回所有对象(不仅仅是未子类化的宠物)。我不知道有什么干净的方法,但我不是NH专家


也许您可以直接查询父表中的鉴别器列?尽管您可能需要响应自定义SQL查询,而不是HQL或ICriteria。

我刚刚做了类似的事情,发现Ayende的这一点非常有用!我使用了连接子类的方法,它很好地支持查询基类


然而,要想在不加入的情况下找到“只宠物”,我认为您需要表/类层次结构方法。或者,您可以使用每个子类的表,只对子类进行左连接,并将其限制为在任何左连接上都不匹配的行。

我刚刚做了类似的事情,发现Ayende的这一点非常有用!我使用了连接子类的方法,它很好地支持查询基类

然而,要想在不加入的情况下找到“只宠物”,我认为您需要表/类层次结构方法。或者,您可以使用每个子类的表,只对子类执行左联接,并将其限制为在任何左联接上都不匹配的行。

这似乎可以正常工作:

我创建了一个视图,使Pet表上的所有列都处于选中状态。然后,我创建了一个映射到视图的简单DTO类。之后,可以使用ICriteria

可能不是最漂亮或最干净的解决方案,但肯定比动态查询字符串更容易使用。

这似乎可以:

我创建了一个视图,使Pet表上的所有列都处于选中状态。然后,我创建了一个映射到视图的简单DTO类。之后,可以使用ICriteria


可能不是最漂亮或最干净的解决方案,但肯定比动态查询字符串更容易使用。

我不相信您可以使用Criteria API实现这一点。但是,您可以使用HQL执行此操作:

var hql = @"from Pet p where p.class = Pet";

我不相信你能用CriteriaAPI做到这一点。但是,您可以使用HQL执行此操作:

var hql = @"from Pet p where p.class = Pet";

为什么不为“PetsOnly”创建一个新的映射,并删除您的鉴别器和其他非必填字段?我认为上面的克里斯托弗也有同样的想法;仍应为您提供完整的插入更新和删除选择支持。宠物只不过是一只宠物…

为什么不为“宠物”创建一个新的映射,并删除您的鉴别器和其他非必填字段?我认为上面的克里斯托弗也有同样的想法;仍应为您提供完整的插入更新和删除选择支持。pet只是一个
pet
..

在很多情况下都足够好:将属性投影到对象本身

请小心使用,因为该对象因其类型不正确而损坏

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>();
var-propsToSelect=Projections.ProjectionList();
foreach(sessionfactory.GetClassMetadata(typeof(Pet)).PropertyNames中的var prop)
{
propsToSelect.Add(Projections.Property(prop.Name)、prop.Name);
}
var results=session.CreateCriteria()
.SetProjection(propsToSelect)
.SetResultTransformer(Transformers.AliasToBean())
.List();

在许多情况下都足够好:将属性投影到对象本身中

请小心使用,因为该对象因其类型不正确而损坏

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>();
var-propsToSelect=Projections.ProjectionList();
foreach(sessionfactory.GetClassMetadata(typeof(Pet)).PropertyNames中的var prop)
{
propsToSelect.Add(Projections.Property(prop.Name)、prop.Name);
}
var results=session.CreateCriteria()
.SetProjection(propsToSelect)
.SetResultTransformer(Transformers.AliasToBean())
.List();

这是Ayende写的一篇很棒的文章。我发现联合子类策略很有趣,我必须对此进行研究。我想知道,如果我想从7张联合表格中获得前10名的结果,那么性能的影响会是什么……这是Ayende的一篇很棒的文章。我发现联合子类策略很有趣,我必须对此进行研究。我想知道如果我想从7个联合表中得到前10个结果,那么性能会受到什么影响……我不得不求助于本机SQL来实现这一点。但是这给了我很多代码来动态构建查询字符串,例如基于过滤器。必须有一种方法来做到这一点,只需ICriteria。Ayende一定考虑过这一点,对吧?我很好奇HQL是否可以做到这一点——本文()指出它可以做到,但您的情况有所不同,因为您将结果限制在基类类型。我不得不求助于本机SQL来实现这一点。但是这给了我很多代码来动态构建查询字符串,例如基于过滤器。必须有一种方法来做到这一点,只需ICriteria。Ayende一定已经考虑过了,对吧?我很好奇这是否可以用HQL实现——本文()指出了这一点