Nhibernate Group By and Alias To Bean

别等时光非礼了梦想. 提交于 2019-12-06 18:59:26

In general, if we want to change our projection to be using GROUP BY, we have to change all "SELECT" parts to be either part of GROUP BY or SUM, MIN ...

We can do it with this kind of syntax

// firstly 
// the original part from the question above
baseQuery.SelectList(list => list
    ...
    .Select(() => joinedBriefBestemmeling.BinnenLand)
       .WithAlias(() => nieuwePrintopdrachtInfo.BestemmelingBinnenLand)
    .Select(() => joinedVerbruiksAdres.Land)
       .WithAlias(() => nieuwePrintopdrachtInfo.LandVerbuiksadres)
    .Select(Projections.Property(() => joinedContactpersoon.ContactpersoonId)
       .As("BestemmelingContactPersoon.ContactPersoonId"))
    .Select(Projections.Property(() => joinedContactpersoonType.Omschrijving)
       .As("BestemmelingContactPersoon.TypeContactPersoon"))
    ...



// changed, to use GROUP BY
baseQuery.SelectList(list => list
    ...
    .SelectGroup(() => joinedBriefBestemmeling.BinnenLand)
       .WithAlias(() => nieuwePrintopdrachtInfo.BestemmelingBinnenLand)
    .SelectGroup(() => joinedVerbruiksAdres.Land)
       .WithAlias(() => nieuwePrintopdrachtInfo.LandVerbuiksadres)
    .Select
       (Projections.Alias
         (Projections.GroupProperty
           (Projections.Property(() => joinedContactpersoon.ContactpersoonId))
         , "BestemmelingContactPersoon.ContactPersoonId"))
    .Select
       (Projections.Alias
         (Projections.GroupProperty
           (Projections.Property(() => joinedContactpersoonType.Omschrijving))
         , "BestemmelingContactPersoon.TypeContactPersoon"))
     ...

So, now we have the GROUP BY (instead of just a SELECT) replacing the original code. But we can do more, we can introduce these (just a quick version) Extension methods (just a light version, really - but working)

public static class Extensions
{
    public static NHibernate.Criterion.Lambda.QueryOverProjectionBuilder<T> GroupByProperty<T>(
        this NHibernate.Criterion.Lambda.QueryOverProjectionBuilder<T> builder, 
        System.Linq.Expressions.Expression<Func<object>> propertyExpression,
        System.Linq.Expressions.Expression<Func<object>> aliasExpression)
    {
        var alias = aliasExpression.ParseProperty();

        var propertyProjection = Projections.Property(propertyExpression);
        var groupProjection = Projections.GroupProperty(propertyProjection);
        var withAliasProjection = Projections.Alias(groupProjection, alias);

        builder.Select(withAliasProjection);
        return builder;
    }

    public static string ParseProperty<TFunc>(this System.Linq.Expressions.Expression<TFunc> expression)
    {
        var body = expression.Body as System.Linq.Expressions.MemberExpression;
        if (body.IsNull())
        {
            return null;
        }

        string propertyName = body.Member.Name;

        ParseParentProperty(body.Expression as System.Linq.Expressions.MemberExpression, ref propertyName);

        // change the   alias.ReferenceName.PropertyName
        // to just            ReferenceName.PropertyName
        var justAPropertyChain = propertyName.Substring(propertyName.IndexOf('.') + 1);
        return justAPropertyChain;
    }

    static void ParseParentProperty(System.Linq.Expressions.MemberExpression expression, ref string propertyName)
    {
        if (expression.IsNull())
        {
            return;
        }
        // Parent.PropertyName
        propertyName = expression.Member.Name + "." + propertyName;

        ParseParentProperty(expression.Expression as System.Linq.Expressions.MemberExpression, ref propertyName);
    }
}

And the above code could be made more readable and common, without any magic string

baseQuery.SelectList(list => list
    ...
    .GroupByProperty(() => joinedBriefBestemmeling.BinnenLand)
       ,() => nieuwePrintopdrachtInfo.BestemmelingBinnenLand)
    .GroupByProperty(() => joinedVerbruiksAdres.Land)
       ,() => nieuwePrintopdrachtInfo.LandVerbuiksadres)
    .GroupByProperty(() => joinedContactpersoon.ContactpersoonId)
       .() => nieuwePrintopdrachtInfo.BestemmelingContactPersoon.ContactPersoonId)
    .GroupByProperty(() => joinedContactpersoonType.Omschrijving)
       .() => nieuwePrintopdrachtInfo.BestemmelingContactPersoon.TypeContactPersoon)
    ...

NOTE IsNull() is also extension

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!