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.