CreateCriteria在一组简单类型上

时间:2014-11-05 06:08:43

标签: c# sql nhibernate nhibernate-criteria

如何使用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个表:

  • 仅使用1列进行测试:Id
  • 包含2列的值:TestId和Value

我的目标是使用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();

就像我用一组对象做的那样,显然失败了。连接是正确的,但如何添加限制?

2 个答案:

答案 0 :(得分:1)

尽管有这个问题,我建议使用IList<ValueEntity>而不是IList<int>

嗯,只有包含值([dbo]。[values])的表可以拥有自己的代理ID列时,这才有效。即使用以下列:IDTestIdValue我们可以引入新实体 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)。不幸的是,你不能使用任何其他别名;
  • 对于sql查询我使用了value - 它将替换?,但由于它是一个字符串 - 我必须使用"'"转义它。