我正在尝试使用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。
答案 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)