session.Query<T>().Where(somecondition).BitOrAggregate(x => x.Rights);

I managed to implement the extension method (by studying nhibernates 
Min/max implementation):

public static AccessRightFlags BitOrAggregate<T>(this IQueryable<T> source, 
Expression<Func<T, EnumRights>> selector)
        {
            return 
source.Provider.Execute<EnumRights>(Expression.Call(null, 
                
((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[]
                    {
                        typeof(T)
                    }), new Expression[]
                    {
                        source.Expression,
                        Expression.Quote(selector)
                    }));
        }

Now it ends up in the expression tree but gave another exception when 
parsing the expression. 
maybe the where filter is too complex, I think the expression itself is 
correct and I am hitting some linq limitations.

Am Mittwoch, 24. Juni 2015 17:35:19 UTC+2 schrieb Oskar Berggren:
>
> How are you using it?
>
>
> /Oskar
>
> 2015-06-24 13:10 GMT+01:00 PeSo <[email protected] <javascript:>>:
>
>> 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] <javascript:>.
>> To post to this group, send email to [email protected] 
>> <javascript:>.
>> Visit this group at http://groups.google.com/group/nhusers.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

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