C# NHibernate中具有多列的IN子句映射

C# NHibernate中具有多列的IN子句映射,c#,nhibernate,icriteria,C#,Nhibernate,Icriteria,我正试图为以下内容编写Nhibernate ICriteria SELECT * FROM foo WHERE (fooKeyColumn1, fooKeyColumn2) IN ( SELECT barKeyColumn1, barKeyColumn2 FROM bar WHERE <some conditions>) 但是,如果我想检查多个属性(如上面的sql示例中所示)的相同属性,则会遇到问题 有没有NHibernate专家可以指导我完成这

我正试图为以下内容编写Nhibernate ICriteria

SELECT * 
FROM foo 
WHERE 
  (fooKeyColumn1, fooKeyColumn2) IN (
    SELECT barKeyColumn1, barKeyColumn2 
    FROM bar
    WHERE <some conditions>)
但是,如果我想检查多个属性(如上面的sql示例中所示)的相同属性,则会遇到问题

有没有NHibernate专家可以指导我完成这项任务


我想在使用ICriteria作为关键组件开发的现有模块中映射此子查询。

您需要自定义
子查询表达式的实现来实现它:

/// <summary>
/// A comparison between multiple properties in the outer query and the
///  result of a subquery
/// Note: DB support of row value constructor is required
/// </summary>
[Serializable]
public class MultiPropertiesSubqueryExpression : SubqueryExpression
{
    private readonly string[] _propertyNames;

    public MultiPropertiesSubqueryExpression(string[] propertyNames, string op, DetachedCriteria dc)
        : base(op, null, dc)
    {
        _propertyNames = propertyNames;
    }

    protected override SqlString ToLeftSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery)
    {
        return new SqlString("(", string.Join(", ", _propertyNames.Select(pn => criteriaQuery.GetColumns(criteria, pn)).SelectMany(x => x)), ")");
    }
}

//
///外部查询中的多个属性与
///子查询的结果
///注意:需要行值构造函数的DB支持
/// 
[可序列化]
公共类多属性SubqueryExpression:SubqueryExpression
{
私有只读字符串[]\u propertyNames;
公共多属性SubQueryExpression(字符串[]属性名称、字符串op、DetachedCriteria dc)
:base(op、null、dc)
{
_propertyNames=propertyNames;
}
受保护的重写SqlString ToLeftSqlString(ICriteria条件,ICriteriaQuery条件)
{
返回新的SqlString(“(”,string.Join(“,”,_propertyNames.Select(pn=>criteriaQuery.GetColumns(criteria,pn))。SelectMany(x=>x)),”);
}
}
用法和示例:

DetachedCriteria detachedCriteria = DetachedCriteria.For(typeof(Bar))
    //.Add(...) //Add some conditions
    .SetProjection(Projections.ProjectionList().Add(Property.ForName("Prop1")).Add(Property.ForName("Prop2")));

var result = session.CreateCriteria(typeof(Foo))
                    .Add(new MultiPropertiesSubqueryExpression(new[] {"Prop1", "Prop2"}, "in", detachedCriteria))
                    .List<Foo>();
DetachedCriteria DetachedCriteria=DetachedCriteria.For(typeof(Bar))
//.Add(…)//添加一些条件
.SetProjection(Projections.ProjectionList().Add(Property.ForName(“Prop1”)).Add(Property.ForName(“Prop2”));
var result=session.CreateCriteria(typeof(Foo))
.Add(新的多属性SubQueryExpression(新[]{“Prop1”,“Prop2”},“in”,detachedCriteria))
.List();
谢谢,它按预期工作:)我在框架中搜索了现有的解决方案,但没有任何关于为SubqueryExpression实现自定义子类的想法。我喜欢你的想法,你刚刚成功了。
DetachedCriteria detachedCriteria = DetachedCriteria.For(typeof(Bar))
    //.Add(...) //Add some conditions
    .SetProjection(Projections.ProjectionList().Add(Property.ForName("Prop1")).Add(Property.ForName("Prop2")));

var result = session.CreateCriteria(typeof(Foo))
                    .Add(new MultiPropertiesSubqueryExpression(new[] {"Prop1", "Prop2"}, "in", detachedCriteria))
                    .List<Foo>();