Order by a property expressed as string in a LINQ Query

This is one of the most common question you got when you show LINQ to Entities or LINQ to Nhibernate to people that are not used to LINQ: How can I order by a property if I have the name of the property expressed as String? I’ve blogged in the past how you can do dynamic sorting and pagination in Entity Framework, but that solution uses ESQL, a dialect to query EF that is similar to NHibernate HQL language.

The solution to the above problem is really simple, you should only start thinking on how the OrderBy LINQ operator works, it basically accepts a lambda that express the ordering criteria, for a customer object it can be something like OrderBy( c=> c.CustomerName). The problem of having the property expressed as string is that the OrderBy method accepts an Expression, so you only need to convert the string to the appropriate expression. The solution is quite simple, you can find the solution in this post, the above code is a slightly variation of the code you find in the previous link.

public static IQueryable<T> OrderByName<T>(
    this IQueryable<T> source,
    string propertyName,
    Boolean isDescending)
{

    if (source == null) throw new ArgumentNullException("source");
    if (propertyName == null) throw new ArgumentNullException("propertyName");

    Type type = typeof(T);
    ParameterExpression arg = Expression.Parameter(type, "x");

    PropertyInfo pi = type.GetProperty(propertyName);
    Expression expr = Expression.Property(arg, pi);
    type = pi.PropertyType;

    Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
    LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);

    String methodName = isDescending ? "OrderByDescending" : "OrderBy";
    object result = typeof(Queryable).GetMethods().Single(
        method => method.Name == methodName
                && method.IsGenericMethodDefinition
                && method.GetGenericArguments().Length == 2
                && method.GetParameters().Length == 2)
        .MakeGenericMethod(typeof(T), type)
        .Invoke(null, new object[] { source, lambda });
    return (IQueryable<T>)result;
}

As you can see this is a simple extension method that extends the IQueryable<T> interface. The code can appear complex, but is really simple because it simply create an expression tree that specify the property you want to use for ordering, then it invoke the correct OrderBy or OrderByDescending method through reflection. The above code is quite complex because it must use reflection, so you could try to create a version that does not need to use reflection to invoke the OrderBy method.

public static IQueryable OrderBy(
    this IQueryable source,
    string propertyName)
{

    if (source == null) throw new ArgumentNullException("source");
    if (propertyName == null) throw new ArgumentNullException("propertyName");

    Type type = typeof(T);
    ParameterExpression arg = Expression.Parameter(type, "x");

    PropertyInfo pi = type.GetProperty(propertyName);
    Expression expr = Expression.Property(arg, pi);
    var lambda = Expression.Lambda(expr, arg);
    return source.OrderBy((Expression>)lambda);
}

This version is much simpler because it uses two Type parameter so it can avoid using reflection to invoke the right OrderBy version. The only disadvantage is that in this version you should specify the right type of the property you are using to order by

  query.OrderBy("Name").ToList();

This call orders by the Name property, specifying that the property is a property of Type String. Clearly this second version is simpler but it is not usable, because in dynamic ordering you does not know in advance the type of the property that will be specified for ordering, this means that the first version based on Mark Gravell’s solution is the only way to go.

Gian Maria.

Generic wrapper for LINQ to Tree

In this post I dealt with a  simple extension function to flatten a tree and in one of the comment Robert shared an interesting link that deal with the creation of a wrapper structure to use LINQ style function on tree structure. That article is really interesting, but the adopted solution requires to create a wrapper for every structure you need to iterate into and I decided to spend a couple of minutes to verify how difficult is writing a generic solution.

Thanks to Func<T> is quite easy to write a wrapper that does not relay on code generation to wrap a specific tree type.

   1: public class TreeWrapper<T> where T : class 

   2:  {

   3:      private readonly T _node;

   4:      private readonly Func<T, IEnumerable<T>> _getChildernFunc;

   5:      private readonly Func<T, T> _getParentFunc;

   6:  

   7:      public TreeWrapper(

   8:          T node,  

   9:          Func<T, IEnumerable<T>> getChildernFunc,

  10:          Func<T, T> getParentFunc)

  11:      {

  12:          _node = node;

  13:          _getChildernFunc = getChildernFunc;

  14:          _getParentFunc = getParentFunc;

  15:      }

As you can see I created a wrapper that takes a node, and a couple of functions, one to find all child of the element, and the other to find the parent of the node. With this simple wrapper writing a Descendants() function is supereasy.

   1: public IEnumerable<T> Descendants()

   2:  {

   3:      return Descendants(_getChildernFunc(_node));

   4:  }

   5:  

   6:  private IEnumerable<T> Descendants(IEnumerable<T> elements)

   7:  {

   8:      return elements.Concat(

   9:          elements.SelectMany(e => Descendants(_getChildernFunc(e))));

  10:  }

Et voilà, this simple method makes this test pass.

   1: [Test]

   2: public void VerifyGenericTreeNodeDescendants()

   3: {

   4:     GenericTreeNode r1 = new GenericTreeNode(1,

   5:             new GenericTreeNode(2,

   6:                         new GenericTreeNode(4)),

   7:             new GenericTreeNode(3),

   8:             new GenericTreeNode(5,

   9:                new GenericTreeNode(6), new GenericTreeNode(7)));

  10:  

  11:     var w = TreeWrapper.Create(r1, n => n.GenericTreeNodes, n => n.Parent);

  12:     w.Descendants().Select(e => e.Id)

  13:         .Should().Have.SameSequenceAs(new int[] {2, 3, 5, 4, 6, 7});

  14: }

The GenericTreeNode class is used only for testing purpose and is a simple class that maintains a reference to parent and a collection of childs. The ancestors function is even simplier.

   1: public IEnumerable<T> Ancestors()

   2: {

   3:     T parent = _getParentFunc(_node);

   4:     while (parent != null)

   5:     {

   6:         yield return parent;

   7:         parent = _getParentFunc(parent);

   8:     }

   9: }

Simply iterate to all parents until the parent is null (reached the root node), but we can still add more interesting methods.

   1: public IEnumerable<T> ElementBeforeSelf()

   2: {

   3:     T parent = _getParentFunc(_node);

   4:     if (parent != null)

   5:     {

   6:         return _getChildernFunc(parent)

   7:             .TakeWhile(e => e != _node);

   8:     }

   9:     return new T[] {};

  10: }

  11:  

  12: public IEnumerable<T> ElementAfterSelf()

  13: {

  14:     T parent = _getParentFunc(_node);

  15:     if (parent != null)

  16:     {

  17:         return _getChildernFunc(parent)

  18:             .SkipWhile(e => e != _node)

  19:             .Skip(1);

  20:     }

  21:     return new T[] { };

  22: }

ElementsBeforeSelft() and ElementsAfterSelf() return all sibling elements (node at same level) before and after the current node element, this makes this test pass.

   1: [Test]

   2: public void VerifyGenericTreeElementBeforeSelf()

   3: {

   4:     GenericTreeNode node;

   5:    new GenericTreeNode(1,

   6:                 new GenericTreeNode(2,

   7:                             new GenericTreeNode(4)),

   8:                 new GenericTreeNode(3),

   9:                 node = new GenericTreeNode(5,

  10:                     new GenericTreeNode(6), new GenericTreeNode(7)),

  11:                  new GenericTreeNode(8),

  12:                  new GenericTreeNode(9));

  13:  

  14:    var w = TreeWrapper.Create(node, n => n.GenericTreeNodes, n => n.Parent);

  15:     w.ElementBeforeSelf().Select(e => e.Id)

  16:         .Should().Have.SameSequenceAs(new int[] { 2, 3 });

  17:  

  18:     w.ElementAfterSelf().Select(e => e.Id)

  19:         .Should().Have.SameSequenceAs(new int[] { 8, 9 });

  20: }

The only disadvantage of this technique, is that I’m not able to write something like this.

   1: w.Descendants().Single(e => e.Id == 5)

   2:     .ElementBeforeSelf().Select(e => e.Id)

   3:     .Should().Have.SameSequenceAs(new int[] { 2, 3 });

This query simple select a single element and then iterates on all the element before self, but it does not compile, because the Descendants() method returns an IEnumerable<T> (T is the wrapped object) and not a IEnumerable<TreeWrapper<T>>. You could modify the Descendants() function to wrap each returned element, but this is not optimal, so I prefer a simply extension method to rewrap an element, that permits me to write this test.

   1: w.Descendants().Single(e => e.Id == 5)

   2:     .TreeWrap(n => n.GenericTreeNodes, n => n.Parent)

   3:     .ElementBeforeSelf().Select(e => e.Id)

   4:     .Should().Have.SameSequenceAs(new int[] { 2, 3 });

This syntax is not bad, the Single LINQ operator permits me to iterate in all Descendants node of the wrapped node, then I need to rewrap again the result to use the ElementBeforeSelf method to use again a function of the TreeWrapper class.

Alk.

Create a tree flatten function to support LINQ queries

Quite often I deal with tree structures where each node can contains a set of children nodes. When is time to cycle through all the nodes, to execute some logic, you need to write a standard recursive function, an operation that is quite boring and repetitive. The question is, is it possible to write a LINQ function called Flatten() that permits you to flatten down a tree of arbitrary depth down to an IEnumerable<T>? The answer is yes.

   1: public static IEnumerable<T> Flatten<T>(

   2:     this T root, 

   3:     Func<T, IEnumerable<T>> getChildernFunc)

   4: {

   5:     yield return root;

   6:  

   7:     IEnumerable<T> descendants = getChildernFunc(root);

   8:     if (descendants != null)

   9:         foreach (T element in descendants)

  10:         {

  11:             foreach (T elementinner in element.Flatten(getChildernFunc))

  12:             {

  13:                 yield return elementinner;

  14:             }

  15:         }

  16: }

It is amazing how simple is writing such a function with the yield return keyword. The code is based on an extension method that accepts an element of type T and a function that is capable to take an element of type T and return its childrens. Inside the body of the function I simply return the root as first, then I iterate on all childrens and for each one recursively call the Flatten function.

How easy. The code probably is not optimum for performance, but it is simple, and I always follow the rule of the three M, Measure Measure Measure, so I do not care for performance problems right now. Now I can write this simple test

   1: [Test]

   2: public void TestRecursivePopulationThreeLevel()

   3: {

   4:     Recursive r1 = new Recursive(1,

   5:            new Recursive(2,

   6:                        new Recursive(4)),

   7:            new Recursive(3));

   8:     var flatten = r1.Flatten(r => r.Recursives);

   9:     flatten.Count().Should().Be.EqualTo(4);

  10:     flatten.Select(r => r.Id).Should().Have.SameSequenceAs(new [] {1, 2, 4, 3});

  11: }

To verify that the code really flatten down the tree. Thanks to Extension Method and yield keyword you can write a simple function that flatten down a hierarchy with fews lines of code.

Alk.

Linq distinct with lambda

Linq Distinct function accepts an IEqualityComparer<T> used to compare values of the IEnumerable to remove “equal” objects to implement the Distinct() function. Sometimes it is more useful to specify a simple Func<T, T, Boolean>, a simple predicate that will implement the concept of Equality between elements. To support such a scenario you can write this simple Extension method.

   1: public static IEnumerable<T> Distinct<T>(

   2:     this IEnumerable<T> source,

   3:     Func<T, T, Boolean> comparer)

   4: {

   5:     return new DistinctByLambda<T>(comparer, source);

   6: }

All the work is done by the DistinctByLambda class, that accepts a reference to the original IEnumerable sequence of elements and the predicate to verify for equality. Here is the code.

   1: public class DistinctByLambda<T> : IEnumerable<T>

   2: {

   3:     private Func<T, T, Boolean> _comparer;

   4:  

   5:     private IEnumerable<T> _source;

   6:  

   7:     public DistinctByLambda(Func<T, T, bool> comparer, IEnumerable<T> source)

   8:     {

   9:         _comparer = comparer;

  10:         _source = source;

  11:     }

  12:  

  13:     public IEnumerator<T> GetEnumerator()

  14:     {

  15:         List<T> alreadyFound = new List<T>();

  16:         foreach (T element in _source)

  17:         {

  18:            if (!alreadyFound.Exists(el => _comparer(el, element)))

  19:            {

  20:                alreadyFound.Add(element);

  21:                yield return element;

  22:            }

  23:             

  24:         }

  25:     }

  26:  

  27:     IEnumerator IEnumerable.GetEnumerator()

  28:     {

  29:         return GetEnumerator();

  30:     }

  31: }

The code is really simple, the IEnumerable.GetEnumerator function is implemented with a simple internal list that stores all distinct elements. For each element of the original list, if it is not equal to any element of the original list it is stored in the list and then returned to the caller; if the element is equal to one element in the list, it gets not returned.

You can use the following function in this simple way.

   1: [Test]

   2: public void VerifyDistinctByLambda()

   3: {

   4:     IList<Test> list = new List<Test>() {new Test("a", 11), new Test("a", 12), new Test("b", 12)};

   5:     var result = list.Distinct((t1, t2) => t1.BlaBla == t2.BlaBla);

   6:     Assert.That(result.Count(), Is.EqualTo(2));

   7:     Assert.That(result, Is.EquivalentTo(new List<Test>() {new Test("a", 11), new Test("b", 12)}));

   8: }

I use a simple Test class that contains two properties, and call Distinct with a  function that compare only the BlaBla property. Now you can use lambda with distinct Smile

Alk.

Linq provider via IEnumerable

If you ever tried to implement a linq provider, you know that this is not a simple task. This is true for a full linq provider, but sometimes we need only a basic support, and in these situations there is probably a simpler approach.

Suppose you need to give LINQ support to find user in Active Directory via LDAP, you need to make query for the various properties of the User object, and you need also to make change to some of these properties and propagate those changes back in the AD. Sounds complicated? Maybe not.

Look at this class.

public class ADUser
{
    System.DirectoryServices.DirectoryEntry userDirEntry = null;
    private DirectoryEntry root;
    public ADUser(DirectoryEntry userDirEntry, DirectoryEntry root)
    {
        this.root = root;
        this.userDirEntry = userDirEntry;
    }

    public String Description
    {
        get { return (String)userDirEntry.Properties["description"].Value; }
        set { userDirEntry.Properties["description"].Value = value; }
    }

    public String UserName
    {
        get { return (String)userDirEntry.Properties["samaccountname"].Value; }

    }

    public void Update()
    {
        userDirEntry.CommitChanges();
    }

    public ADGroupCollection Groups { get; private set; }
}

As you can see, this is a simple object that wraps a DirectoryEntry related to an ActiveDirectory user, it wraps only Name and Description, but it can be updated to support all user properties. Now I create another simply class.

public class ADUsers : IEnumerable<ADUser>
{
    private IList<ADUser> Users;
    System.DirectoryServices.DirectoryEntry root = null;
    public ADUsers(System.DirectoryServices.DirectoryEntry root)
    {
        this.root = root;
        Users = new List<ADUser>();
        DirectorySearcher search = new DirectorySearcher(root);
        search.Filter = "(&(objectClass=user)(objectCategory=person))";
        search.PropertiesToLoad.Add("cn");
        SearchResultCollection results = search.FindAll();
        foreach (SearchResult result in results)
        {
            var de = result.GetDirectoryEntry();
            Users.Add(new ADUser(de, root));
        }
    }
    public IEnumerator<ADUser> GetEnumerator()
    {
        return Users.GetEnumerator();
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

This is a real simple classes, it accepts a DirectoryEntry root used to query the Ldap, then it retrieves all the users object with a simple LDap query issued by DirectorySearcher object, for each result, it builds a wrapper ADuser. Now that we have these two simple classes we can write.

image

Since I loaded in memory a wrapper for each object, I can issue LINQ queries against the AdUsers, because I can rely on the support of Linq 2 Object, simply making AdUsers implementing IEnumerable. Since everything is in memory we can issue condition like u.UserName.Contains(“amp”) or whatever you like.

Surely this is not the optimal solution, but is quick and works well. The main drawback is that all Users needs to be loaded into memory, so we are using more resources respect a full LINQ provider, that can analyze the expression and retrieve only users that satisfies the query. But since we are not expecting Thousands of users, this can be a viable KISS solution.

This simple example shows that, to support LINQ for some source, sometimes there is no reason to pass for the full IQueryable<T>.

Alk.

Tags: