如何使用CreateCriteria
查询简单类型的集合?
例如,我有1个班级
public class Test
{
public virtual Guid Id { get; set; }
private ICollection<int> _values = new HashedSet<int>();
public virtual ICollection<int> Values
{
get { return _values; }
}
}
支持它的2个表:
我的目标是使用CreateCriteria
重写以下查询:
select * from test t
inner join values v on v.TestId = t.Id
where v.Value = 10
我试过这个:
Session.CreateCriteria<Test>("test")
.CreateAlias("test.Values", "values")
.Add(Restrictions.Eq("values", 10))
.List();
就像我用一组对象做的那样,显然失败了。连接是正确的,但如何添加限制?
答案 0 :(得分:1)
尽管有这个问题,我建议使用IList<ValueEntity>
而不是IList<int>
。
嗯,只有包含值([dbo]。[values])的表可以拥有自己的代理ID列时,这才有效。即使用以下列:ID
,TestId
,Value
我们可以引入新实体 ValueEntity 并将其映射为第一级公民。然后查询它将变得更加简单,包括子查询..
但我知道这不是问题。
事实上,有一个解决方案,有上述问题的答案。但请,至少尝试考虑上述建议......
用于IList<int>
集合查询的NHibernate解决方案是:
Session.CreateCriteria<Test>("test")
.CreateAlias("test.Values", "values")
// we add magic keyword ".elements" here
.Add(Restrictions.Eq("values.elements", 10))
.List();
请参阅“.elements”,其中有一点记录不清here。还提供了对此类似问题的答案:NHibernate How do I query against an IList<string> property?
答案 1 :(得分:0)
elements
的方法对我没用。不知怎的,NHibernate选错了别名......
所以来自
CurrentSession.CreateCriteria<EmployeeIntranetSettings>("settings")
.CreateAlias("settings.DefaultLMSOwnershipCapacities", "capacity")
.Add(Restrictions.Eq("capacity.elements", OwnershipCapacity.VehicleFinance))
.SetProjection(Projections.Id())
.List<Guid>();
创建了
SELECT this_.Id as y0_
FROM intranet.sfEmployeeIntranetSettings this_
inner join contact.sfEmployeeDefaultLMSOwnershipCapacities defaultlms3_ on this_.Id=defaultlms3_.EmployeeId
WHERE capacity1_.Capacity = @p0
如您所见 - 容量的别名不同。
所以我会先讨论有关ValueType实体的建议,尽管它可能是针对DDD的。作为具有当前架构的工作解决方案(至少对我而言):
CurrentSession.CreateCriteria<Employee>("employee")
.Add(Expression.Sql(
"Exists (select top 1 null from contact.sfEmployeeDefaultLMSOwnershipCapacities dc where dc.EmployeeId = {alias}.Id and dc.Capacity = ?)",
"'" + OwnershipCapacity.VehicleFinance + "'",
NHibernateUtil.String))
.SetProjection(Projections.Id())
.List<Guid>();
这里很少有兴趣点:
{alias}
将导致根实体别名(employee)。不幸的是,你不能使用任何其他别名; value
- 它将替换?
,但由于它是一个字符串 - 我必须使用"'"
转义它。