![](/img/trans.png)
[英]NHibernate session.Query<ISomeInterface>().Count returns wrong count
[英]NHibernate RowCountInt64 returns wrong count with transformed query
我在执行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,我不满意。 在我正在使用它的实现中它可能就足够了,但是在其他地方可能存在需要很长时间的情况,因此任何其他建议都值得赞赏。
编辑:我唯一不喜欢上面的解决方案是它返回一个int,所以通过一些挖掘,我设法用另一个投影类修复它:
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>();
}
问题似乎是Transformers.DistinctRootEntity
很自然你得到4行计数,3列表。 当执行查询重新调整4行并删除重复的内存时, DistinctRootEntity
可以正常工作。
您可以将query.RowCountInt64()
与正确的查询一起使用。
//
// Summary:
// Clones the QueryOver, removes orders and paging, and projects the row-count
// (Int64) for the query
IQueryOver<TRoot, TRoot> ToRowCountInt64Query();
//
// Summary:
// Short for ToRowCountInt64Query().SingleOrDefault<long>()
long RowCountInt64();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.