繁体   English   中英

NHibernate RowCountInt64返回带有转换查询的错误计数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM