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

C# 使用NHibernate函数使用QueryOver过滤结果,c#,mysql,sql,sql-server,nhibernate,C#,Mysql,Sql,Sql Server,Nhibernate,我正在尝试使用SQL函数来过滤查询结果。我在SQL中有一个名为SplitKeys的函数,它接受一个csv字符串并返回一个整数表。我希望生成以下SQL或与其相近的SQL: 从MemberKey所在的成员中选择*,从SplitKeys'1,2,3'中选择* 我在使用QueryOver,似乎找不到生成where子句的东西。因为我无法让它工作,所以我创建了另一个函数,该函数接受字符串和id,如果id在列表中,则返回id,如果不在列表中,则返回-1 session.QueryOver<Member&

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

从MemberKey所在的成员中选择*,从SplitKeys'1,2,3'中选择*

我在使用QueryOver,似乎找不到生成where子句的东西。因为我无法让它工作,所以我创建了另一个函数,该函数接受字符串和id,如果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.WhereRestrictionOnx=>x.MemberKey.IsInGintKeyList

我看了又看,似乎找不到这样做的人,也找不到让NHibernate和C编译器喜欢它的人。我试过了,但没用。此变体和其他变体要么引发System.In32没有映射的异常,要么不返回任何内容

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

我尝试为结果创建某种映射,但我无法做到,因为没有表。我尝试使用.In函数,但它不接受Projects.SqlFunction。

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

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

是的,成功了。几乎两个细微的变化。它是{alias}.MemberKey,您必须调用SqlString.parse而不是新的SqlString。