简体   繁体   English

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

[英]NHibernate RowCountInt64 returns wrong count with transformed query

I am experiencing a weird error while executing an NHibernate Query. 我在执行NHibernate查询时遇到了一个奇怪的错误。 I have a query of type IQueryOver<ExternalUser, ExternalUser> which is filtered and transformed (using DistinctRootEntity, which i am guessing is causing the problem). 我有一个类型IQueryOver<ExternalUser, ExternalUser>的查询,它被过滤和转换(使用DistinctRootEntity,我猜这是导致问题)。 I create the query like this: 我创建这样的查询:

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);

When i execute query.RowCountInt64() i get 4. 当我执行query.RowCountInt64()我得到4。

When i execute query.List() i get 3 items back. 当我执行query.List()我得到3个项目。

I have also tried query.ToRowCountInt64Query().List<long>().Sum() which also gives me 4. 我也尝试过query.ToRowCountInt64Query().List<long>().Sum()也给了我4。

I also tried query.ToRowCountInt64Query().FutureValue<long>().Value which also gives me 4. 我也尝试过query.ToRowCountInt64Query().FutureValue<long>().Value也给了我4。

Any ideas how to solve this? 任何想法如何解决这个问题?

I found a solution that works: 我找到了一个有效的解决方案:

totalCount = query.Clone()
                  .Select(Projections.CountDistinct<User>(x => x.Id))
                  .SingleOrDefault<int>();

...but my solution restricts me to Int32 which i'm not happy about. ...但我的解决方案限制我使用Int32,我不满意。 It will probably suffice in the implementation where i'm using it, but there might be cases elsewhere where long is needed, so any other suggestions are appreciated. 在我正在使用它的实现中它可能就足够了,但是在其他地方可能存在需要很长时间的情况,因此任何其他建议都值得赞赏。

EDIT: The only thing i didn't like with the solution above was that it returned an int, so with some digging, i managed to fix that with another projection class: 编辑:我唯一不喜欢上面的解决方案是它返回一个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();
    }
}

...and with this class i can get my count like this (which could be refined further with an extension method, but this is enough for me): ...和这个类我可以得到这样的计数(可以通过扩展方法进一步细化,但这对我来说已经足够了):

totalCount = query.Clone()
                  .Select(Int64CountProjection.Distinct<User>(x => x.Id))
                  .SingleOrDefault<long>();

EDIT #2 I couldn't leave well alone, so i implemented an extension method aswell: 编辑#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>();
     }

The problems seems be Transformers.DistinctRootEntity is natural you get 4 in row count, and 3 on a list. 问题似乎是Transformers.DistinctRootEntity很自然你得到4行计数,3列表。 The DistinctRootEntity works when the query has been executed retuning 4 rows and removing duplicated in memory. 当执行查询重新调整4行并删除重复的内存时, DistinctRootEntity可以正常工作。

You can use query.RowCountInt64() with the correct query. 您可以将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