我有以下查询:
var list = repositoy.Query<MyClass>.Select(domain => new MyDto()
{
Id = domain.Id,
StringComma = string.Join(",", domain.MyList.Select(y => y.Name))
});
效果很好:
list.ToList();
但如果我试图获得伯爵,我得到一个例外:
list.Count();
异常
NHibernate.Hql.Ast.ANTLR.QuerySyntaxException
A recognition error occurred. [.Count[MyDto](.Select[MyClass,MyDto](NHibernate.Linq.NhQueryable`1[MyClass], Quote((domain, ) => (new MyDto()domain.Iddomain.Name.Join(p1, .Select[MyListClass,System.String](domain.MyList, (y, ) => (y.Name), ), ))), ), )]
知道如何在不使用ToList
的情况下解决问题吗?
答案 0 :(得分:1)
关键是,我们不应该将Count()
称为投影。所以这将有效
var query = repositoy.Query<MyClass>;
var list = query.Select(domain => new MyDto()
{
Id = domain.Id,
StringComma = string.Join(",", domain.MyList.Select(y => y.Name))
});
var count = query.Count();
当我们使用ICriteria
查询时,正确的语法将是
var criteria = ... // criteria, with WHERE, SELECT, ORDER BY...
// HERE cleaned up, just to contain WHERE clause
var totalCountCriteria = CriteriaTransformer.TransformToRowCount(criteria);
因此,对于 Count - 使用最简单的查询,即包含相同的JOIN和WHERE部分
答案 1 :(得分:1)
如果你真的不需要结果,但只需要计数,那么你甚至不应该费心去编写.Select()子句。 Radim发布的答案是获得结果和计数的好方法,但如果您的数据库支持它,请使用将来的查询在数据库的同一往返中执行:
var query = repository.Query<MyClass>;
var list = query.Select(domain => new MyDto()
{
Id = domain.Id,
StringComma = string.Join(",", domain.MyList.Select(y => y.Name))
}).ToFuture();
var countFuture = query.Count().ToFutureValue();
int actualCount = countFuture.Value; //queries are actually executed here
请注意,在3.3.3之前的NH中,这仍然会执行两次往返(参见https://nhibernate.jira.com/browse/NH-3184),但它会起作用,如果你升级NH,你会获得(次要的)性能升压。