带有投影和计数错误的 NHibernate Linq 查询

NHibernate Linq Query with Projection and Count error

我有以下查询:

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 的情况下解决这个问题吗?

重点是,我们不应该调用 Count() over projection。所以这会起作用

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 部分

如果您真的不需要结果,而只需要计数,那么您甚至不必费心编写 .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,你会得到一个(次要的) ) 性能提升。