I think I understand now why the BitOrAggregate doesnot register.

The method is an extension method. Its implementation:

public static EnumRights BitOrAggregate(this IQueryable<AccessRight> input, 
Expression<Func<AccessRight, EnumRights >> getter)
        {
            EnumRights defaultValue = EnumRights.unknown;
            return input.Select(getter).Aggregate(defaultValue, (x, y) => x 
| y);
        }

BitOrAggregate gets never added to the expression, instead a select gets 
added and Aggregate (which isn't supported by Nhib SQL but gets executed in 
C#).

But how would I add/register such a grouping/sum function?



Am Freitag, 12. Juni 2015 14:53:22 UTC+2 schrieb PeSo:
>
> Hi,
> I am having problems mapping an BITORAGGREGATE SQl Function to 
> Linq.NHibernate.
> I am using NH 4.0.3 and the  Oracle10Provider.
> The (simplified) domain model looks like this:
>
> public class Person {
>     public virtual int Id { get; set;}
>  
>     public virtual string Name { get;set; }
> }
>
> public class AccessRight {
>     public virtual int Id { get; set;}
>      
>     public virtual Person Person { get; set;}
>
>     public virtual EnumRights AssignedRights { get;set; }
> }
>
> EnumRights is a flags enum with Values Read,Write,Delete,...
>
> Basically I want to write a query that gives me all AccessRights that are 
> assigned to a given person 
> (Note that in the non simplified version rights can also be inherited from 
> Usergroups that the user belongs to!).
> To be able to use this query as a filter I must compact the resultset of 
> the subquery to a single EnumRights value 
> by bit-oring all AssignedRights that my subquery returns.
>
> For that I have written the BitOrAggregate:
>
> SELECT BITORAGGREGATE(x.AccessRights) FROM AccessRight x where x.PersonId 
> = 7
>
> which returns a single EnumRights value.
>
> But I am not able to successfully map this function.
>
> I wrote the C# Linq-Code:
>
>  public static EnumRights BitOrAggregate(this IQueryable<AccessRight> 
> input, Expression<Func<AccessRight, EnumRights >> getter)
>         {
>             ...
>         }
>
> The BaseHqlgenerator:
>
> public class BitOrAggregateAccessRightFlags : BaseHqlGeneratorForMethod
>     {
>         public BitOrAggregateAccessRightFlags()
>         {
>             SupportedMethods = new[] { 
>                 ReflectionHelper.GetMethod(() => 
> LinqExtension.BitOrAggregate(null,null))
>             };
>         }
>
>         public override HqlTreeNode BuildHql(MethodInfo method, Expression 
> targetObject,
>             System.Collections.ObjectModel.ReadOnlyCollection<Expression> 
> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
>         {
>             HqlExpression hqlExpression = 
> visitor.Visit(arguments[1]).AsExpression();
>                 return treeBuilder.MethodCall("BITORAGGREGATE", 
> hqlExpression);
>         }
>     }
>
> And I added the new generator to the linq registry.
>
> public class ExtendedLinqToHqlGeneratorsRegistry : 
> DefaultLinqToHqlGeneratorsRegistry
>     {
>         public ExtendedLinqToHqlGeneratorsRegistry() : base()
>         {
>             RegisterGenerator(ReflectionHelper.GetMethod(() => 
> LinqExtension.BitOrAggregate(null,null)),
>                                 new BitOrAggregateAccessRightFlags());
>         }
>     }
>
> But it still enters the C# Linq implementation instead of emitting 
> BITORAGGREGATE.
> I clearly must be doing something wrong.
> Any ideas/obvious mistakes?
> Thanks,
> Peter
>
>
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/nhusers.
For more options, visit https://groups.google.com/d/optout.

Reply via email to