Create a custom ResultOperator

Skip to first unread message

Jordi Cabré

Sep 21, 2016, 7:20:28 AM9/21/16
to re-motion Users
I've create an extension method SingleOrEmpty:

public static TSource SingleOrEmpty<TSource>(this IEnumerable<TSource> source)
if (source.Any())
return source.SingleOrDefault();
return Activator.CreateInstance<TSource>();

As you can see I'm trying to return an instance of TSource using a single constructor.

I would like to use tihs method but I don't know how to declare it as a ResultOperator.

Is it possible?

Fabian Schmied

Sep 21, 2016, 3:25:47 PM9/21/16
It might not be 100% up to date, but the basic idea should still work.

Best regards,

You received this message because you are subscribed to the Google Groups "re-motion Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
To post to this group, send email to
Visit this group at
For more options, visit

Jordi Cabré

Sep 22, 2016, 7:49:05 AM9/22/16
to re-motion Users

It's been really usefull this documentation. Thanks and great job.

As far I've been able to figure out, I've created a ResultOperator (: SequenceTypePreservingResultOperatorBase) and a re-linq hook (: ResultOperatorExpressionNodeBase) and finally register it on re-linq.

I've created my custom Linq provider using re-linq in order to get information from a server. So, I provide some util methods (MetaInfoKey bellow) in order to create Expressions in order to avoid work to the user. For example:

.GroupBy(LinqTreeExtensions.Query<Backend.Domain.FollowUpActivity>(f => f).MetaInfoKey<Backend.Domain.FollowUpActivity, string>("Key"))
.Select(g => new { Value = g.Key, Count = g.Count() });

I need these custom made expressions are `compatible` with "Linq over collections" provider.
Shortly, the expression is generating MetaInfoKey is: {f => Convert(f.Metainfos.Where(m => (m.Key == "Key")).SingleOrEmpty().Value)}

In order to build it I do:

ParameterExpression entityParameter = expr.Parameters.First();
ParameterExpression metaInfoParameterExpression = Expression.Parameter(collGenericType, "m");

MemberExpression collectionMemberExpression = Expression.Property(entityParameter, collectionPropertyInfo);
MethodInfo whereMethod = typeof(Enumerable).GetMethods().Where(m => m.Name.Equals("Where") && m.GetParameters().Length == 2).First().MakeGenericMethod(collGenericType);
MethodInfo singleMethod = typeof(LinqTreeExtensions).GetMethods().Where(m => m.Name.Equals("SingleOrEmpty") && m.GetParameters().Length == 1).First().MakeGenericMethod(collGenericType);

LambdaExpression innerCondition = Expression.Lambda(
Expression.GetDelegateType(collGenericType, typeof(bool)),
Expression.Property(metaInfoParameterExpression, "Key"),

MethodCallExpression whereCallExpression = Expression.Call(whereMethod, collectionMemberExpression, innerCondition);
MethodCallExpression singleCallExpression = Expression.Call(singleMethod, whereCallExpression);
MemberExpression memberExpression = Expression.Property(singleCallExpression, "Value");
UnaryExpression convertExpression = Expression.Convert(memberExpression, typeof(TKeyType));
Expression<Func<TElementType, TKeyType>> lambdaExpression = Expression.Lambda<Func<TElementType, TKeyType>>(convertExpression, entityParameter);

return lambdaExpression;

The first problem I'm facing up is how to implement the
SingleOrEmpty extension method:

public static IQueryable<TSource> SingleOrEmpty<TSource>(this IQueryable<TSource> source)
return source.Provider.CreateQuery<TSource>(

I'm guessing it's building a CallMethodExpression, but where's the implementation? Remember that it's to be performed over Linq-Collection as well...

I hope I've explained so well.

Fabian Schmied

Sep 24, 2016, 3:29:33 AM9/24/16
> I'm guessing it's building a CallMethodExpression, but where's the
> implementation? Remember that it's to be performed over
> Linq-Collection as well...

Take a look at SingleOrDefault as a template for your implementation. There are two SingleOrDefault methods; one is defined on IEnumerable, the other on IQueryable. The IEnumerable one has a "real" implementation; it's meant to be used with normal enumerable sequences and collections. The IQueryable one has the "meta" implementation you've already written for your own method; it's meant to be used when constructing queries to be translated by a LINQ provider.

With re-linq, you usually handle both variants because even the method for IEnumerable can be used within a query, for subqueries.

Best regards,

Reply all
Reply to author
0 new messages