使用NHibernate函数使用QueryOver过滤结果

时间:2014-03-28 22:44:48

标签: c# mysql sql sql-server nhibernate

我正在尝试使用SQL函数来过滤查询结果。我在SQL中有一个名为SplitKeys的函数,它接受一个csv字符串并返回一个整数表。我想生成以下SQL(或接近它):

从MemberKey中的成员中选择*(从SplitKeys('1,2,3')中选择*)

我正在使用QueryOver,似乎无法获得生成where子句的东西。由于我无法使用它,我创建了另一个带有字符串和id的函数,如果它在列表中则返回id,如果不是则返回-1。

session.QueryOver<Member>().Where(
    Restrictions.Ge(
        Projections.SqlFunction(
            "dbo.IsKeyInList",
            NHibernateUtil.StringClob,
            new[]
            {
                Projections.Constant(
                    keyList,
                    NHibernateUtil.StringClob),
                Projections.Constant(',', NHibernateUtil.Character),
                Projections.Property<Member>(x => x.MemberKey)
            }),
    0));

这很好用,除非它很慢。使用第一个查询,该函数被调用一次,然后可以根据表进行过滤。在第二个中,它为每一行调用函数。

我最初将此作为一个int列表并将其传入。但是,问题是列表中的每个元素都是SQL中的参数,最大参数是2100.

session.QueryOver()。WhereRestrictionOn(x =&gt; x.MemberKey).IsInG(intKeyList);

我看起来和看起来似乎找不到那样做的人,或者让NHibernate和C#编译器喜欢它。我试过这个并没有用。这个和其他变体要么在System.In32的No Mapping中抛出异常,要么它什么也不返回。

var keys =
    session.QueryOver<MemberKey>()
        .Select(
            Projections.SqlFunction(
                "dbo.SplitKeysCSV",
                NHibernateUtil.StringClob,
                new[] { 
                    Projections.Constant(keyList),
                    Projections.Constant(delimiter),
                }));

我尝试为结果创建某种映射,但我不能这样做,因为没有表。我尝试使用.In()函数,但是它不接受Projects.SqlFunction。

1 个答案:

答案 0 :(得分:0)

您可以使用SqlCriterion执行此操作:

var sqlCrit = new SQLCriterion("{alias}.MemberKey in (SELECT * FROM dbo.SplitKeys(?))",
                new[]{ keyList }, new IType[]{ NHibernateUtil.String })
var keys = session.QueryOver<Member>()
            .Where(sqlCrit)