假设我有课程Animal
,Cat
和Dog
。 Cat
和Dog
继承自Animal
。请考虑以下代码:
var query = from animal in session.Linq<Animal>()
where
animal.Color == "White"
select animal;
如何在上述查询中添加条件以查询实体类型?例如animal.Type == typeof(Cat)
。
答案 0 :(得分:11)
新提供商支持此功能:
var query = from animal in session.Query<Animal>()
where animal.Color == "White" &&
animal is Cat
select animal;
答案 1 :(得分:1)
与NH 2.1.2兼容的LINQ-to-NHibernate版本不支持在运行时按类型查询。
// DOES NOT WORK WITH NH 2.1.2 & LINQ-to-NH
var desiredType = typeof(Cat);
var query = from animal in session.Linq<Animal>()
where animal.Color == "White"
&& animal.GetType() == desiredType
select animal;
// This results in an ArgumentOutOfRangeException in the LINQ provider
您可以按照评论中的建议在内存中执行此操作:
var desiredType = typeof(Cat);
var query = from animal in session.Linq<Animal>()
where animal.Color == "White"
select animal;
var animals = query.ToList();
var whiteCats = from animal in animals.AsQueryable()
where animal.GetType() == desiredType
select animal;
通过执行query.ToList(),您将读回所有白色动物,然后使用LINQ-to-Objects执行类型查询。 (根据您的确切查询和映射,您可能不得不担心延迟代理,因此检查对象的类型是否可以分配给desiredType。)这样做的主要缺点是回读的数据超过了需要的数据以便按动物过滤输入内存。根据您的域和查询,这可能是也可能不是一个大问题。
如果你不能升级到NHibernate trunk(又名NH3),我建议你不要在这个查询中使用LINQ-to-NHibernate,而是使用Criteria。
var desiredType = typeof(Cat);
var query = session.CreateCriteria(desiredType)
.Add(Restrictions.Eq("Color", "White")
.List<Animal>();
N.B。这应该是显而易见的,但我要明确说明一下。没有理由不能将Criteria用于此查询,而将LINQ-to-NHibernate用于其他查询。您可以自由地在NHibernate中混合匹配查询技术。
答案 2 :(得分:1)
您可以映射使用鉴别器列作为公式一部分的只读属性。查询此列将允许您区分具有当前nhcontrib提供程序的类型。
在我对类似问题here的回答中可以找到进一步的指导。