0

我正在使用 NHibernate 并且我有一个要运行的查询,其中涉及返回整个表加上一个countand group by。根据我在网上阅读的内容,您无法使用 NHibernate Criteria 执行此操作。

为了解决这个问题,我使用了一个命名查询:

SELECT id, COUNT(id) AS myCount
FROM foo INNER JOIN bah
    ON foo.id = bah.fooId
WHERE foo.Name LIKE :name
GROUP BY fooId

当我只想传入一个参数时,这很好用。

不过,我真正想要实现的是:

SELECT id, COUNT(id) AS myCount
FROM foo
INNER JOIN bah ON foo.id = bah.fooId
WHERE foo.Name LIKE :name1
    OR foo.Name LIKE :name2
    OR foo.Name LIKE :name3
GROUP BY fooId

参数的数量是可变的,因此我想要匹配的名称可能有 2 个或 3 个或 4 个。

我使用带有以下代码的标准解决了它:

ICriteria criteria = session.CreateCriteria(typeof (Foo)).CreateCriteria("Bah");
Disjunction disjunction = Restrictions.Disjunction();
foreach (Foo foo in fooToFind)
{
    disjunction.Add(Restrictions.Like("Name", "%" + Foo.Name + "%"));
}
criteria.Add(disjunction);
result = criteria.List<Foo>();

(就像我上面说的:看起来我不能使用它,因为我不能将计数作为回报的一部分返回。)

所以我尝试使用query.SetParameterList

IQuery query = session.GetNamedQuery("myNamedQuery");
query.SetParameterList("name", new string[] {"eeeny", "meeny"});

然而,这似乎给了我 sql:

SELECT id, COUNT(id) AS myCount
FROM foo
INNER JOIN bah ON foo.id = bah.fooId
WHERE foo.Name LIKE 'eeny','meeny'
GROUP BY food

所以 nHibernate 不喜欢逗号。

将查询更改为

SELECT id, COUNT(id) AS myCount
FROM foo
INNER JOIN bah ON foo.id = bah.fooId
WHERE foo.Name IN (:name)
GROUP BY fooId

效果很好,但没有给我想要的结果。

有谁知道我怎样才能达到这个结果 - 使用任何 nHibernate 方法?

SELECT id, COUNT(id) AS myCount
FROM foo
INNER JOIN bah ON foo.id = bah.fooId
WHERE foo.Name LIKE :name1
    OR foo.Name LIKE :name2
    OR foo.Name LIKE :name3
GROUP BY fooId
4

2 回答 2

0

似乎命名查询不是您的方案的正确选择。相反,您应该动态构建查询,如下所示:

    var querybase="select f.Id,Count(f.Id) from foo WHERE {0} group by f.Id";
    var whereClause=new StringBuilder();
    whereClause.Append("0=1 ");
    foreach(var name in names)
    {
       whereClause.Append(string.Format("OR f.Name Like '{0}' ",name));
    }

    var query=string.Format(querybase,whereClasue);

为了简单起见,我忽略了参数并将名称值添加到 where 子句,由于打开了 SQL 注入的位置,因此不建议这样做,但是您可以在此处添加参数名称,然后在查询中设置参数值。

于 2009-09-05T09:50:07.797 回答
0

您的原始查询

SELECT id, COUNT(id) AS myCount FROM
foo INNER JOIN bah ON foo.id = bah.fooId 
WHERE foo.Name LIKE :name1
OR foo.Name LIKE :name2 
OR foo.Name LIKE :name3
GROUP BY fooId

对于 nHibernate

SELECT id, COUNT(id) AS myCount FROM
foo INNER JOIN bah ON foo.id = bah.fooId 
WHERE 
foo.Name IN (:names)
GROUP BY fooId

从理论上讲,如果

1) you set yours up as a Named Query
2) you have an entity setup as the <return class="">
3) you use SetParameterList
4) names is a string array or ArrayList

例如,您生成的 hbm 文件

  <sql-query name="MyFooCount" cacheable="false" read-only="true">
  <return alias="" class="FooCountEntity" />
    <![CDATA[
Your query here...
    ]]>
  </sql-query>

例如你的 C# 文件

string [] mynames = {"peter", "olivia", "charles"};
query.SetParameterList ("names", mynames);
于 2010-09-07T00:35:39.537 回答