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

时间:2015-03-25 17:18:51

标签: nhibernate iqueryable linq-to-nhibernate

我有以下查询:

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

2 个答案:

答案 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,你会获得(次要的)性能升压。