我在执行 NHibernate 查询时遇到一个奇怪的错误。
我有一个类型为 IQueryOver<ExternalUser, ExternalUser>
的查询它被过滤和转换(使用 DistinctRootEntity,我猜这是导致问题的原因)。我创建这样的查询:
List<Guid> companyList = /* some guids */
Company company = null;
var query = _session.QueryOver<ExternalUser>()
.JoinAlias(x => x.Companies, () => company)
.Where(() => company.Id.IsIn(companyList))
.TransformUsing(Transformers.DistinctRootEntity);
当我执行
query.RowCountInt64()
我得到 4。当我执行
query.List()
我拿回了 3 件元素。我也试过
query.ToRowCountInt64Query().List<long>().Sum()
这也给了我 4。我也试过
query.ToRowCountInt64Query().FutureValue<long>().Value
这也给了我 4。任何想法如何解决这个问题?
最佳答案
我找到了一个有效的解决方案:
totalCount = query.Clone()
.Select(Projections.CountDistinct<User>(x => x.Id))
.SingleOrDefault<int>();
...但我的解决方案将我限制为 Int32,我对此并不满意。在我使用它的实现中它可能就足够了,但在其他地方可能需要很长时间,所以任何其他建议都值得赞赏。
编辑:
我唯一不喜欢上面的解决方案的是它返回了一个整数,所以通过一些挖掘,我设法用另一个投影类来解决这个问题:
public class Int64CountProjection : CountProjection
{
protected internal Int64CountProjection(string prop) : base(prop) {}
protected internal Int64CountProjection(IProjection projection) : base(projection) {}
public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
return new IType[] { NHibernateUtil.Int64 };
}
public static CountProjection Distinct<T>(Expression<Func<T, object>> expression)
{
return new Int64CountProjection(ExpressionProcessor.FindMemberExpression(expression.Body)).SetDistinct();
}
}
...有了这个类,我可以得到这样的计数(可以使用扩展方法进一步细化,但这对我来说已经足够了):
totalCount = query.Clone()
.Select(Int64CountProjection.Distinct<User>(x => x.Id))
.SingleOrDefault<long>();
编辑 #2
我不能一个人呆着,所以我也实现了一个扩展方法:
public static long CorrectRowCount<TRoot>(this IQueryOver<TRoot> query) where TRoot : IEntity
{
return query.Clone()
.Select(Int64CountProjection.Distinct<TRoot>(x => x.Id))
.ClearOrders()
.Skip(0)
.Take(RowSelection.NoValue)
.SingleOrDefault<long>();
}
关于NHibernate RowCountInt64 使用转换后的查询返回错误的计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22304693/