.NET, Architecture, ALM, Cloud

Publicité

Méthode d'extension OrderBy(string, direction)

Voici un exemple dimplémentation pour ajouter une méthode d'extension sur IQueryable<TSource> pour effectuer vos tris sur un nom de membre (sans méthode lambda) et préciser la direction (éviter d'avoir à appeller dans un cas le "OrderBy" ou dans l'autre le "OrderByDescending") :

public static class QueryableExtensions
    {
        public static IOrderedQueryable<TSource> OrderBy<TSource>(
            this IQueryable<TSource> query,
            string dataMember,
            ListSortDirection direction)
        {
            string orderByMethodName = (direction == ListSortDirection.Ascending) ? "OrderBy" : "OrderByDescending";
            PropertyInfo property = typeof(TSource).GetProperty(dataMember);
            dynamic sortExpression = BuildOrderByExpression<TSource>(dataMember, property.PropertyType);
 

            MethodInfo orderByMethod = typeof(System.Linq.Queryable).GetMethods()

                .Single(Method => Method.Name == orderByMethodName

                    && Method.GetParameters().Count() == 2

                    && Method.GetParameters()[1].ParameterType.ToString() == "System.Linq.Expressions.Expression`1[System.Func`2[TSource,TKey]]"

                    );

 

            return

            (IOrderedQueryable<TSource>)orderByMethod.MakeGenericMethod(typeof(TSource), property.PropertyType)
                .Invoke(query, new object[2] { query, sortExpression });
        }
 

        private static dynamic BuildOrderByExpression<TSource>(string member, Type memberType)
        {
            return typeof(QueryableExtensions)
                .GetMethod("BuildOrderByExpression", BindingFlags.NonPublic | BindingFlags.Static, null, new Type[1] { typeof(string) }, null)
                .MakeGenericMethod(typeof(TSource), memberType).Invoke(null, new object[1] { member });
        }
 

        private static Expression<Func<TSource, Key>> BuildOrderByExpression<TSource, Key>(string member)
        {
            var param = Expression.Parameter(typeof(TSource), "entity");

            return Expression.Lambda<Func<TSource, Key>>(
                Expression.Property(param, member),
                param);
        }
    }

 

Et un test unitaire : 

 public class User
    {
        public string FirstName { get; set; }
 
        public string LastName { get; set; }
    }
 
    [TestClass]
    public class QueryableExtensionsTest
    {
        [TestMethod]
        public void SortListOKTest()
        {
            List<User> users = new List<User>()
            {
                new User(){ FirstName = "Joe", LastName = "Patterson" },
                new User(){ FirstName = "Richard", LastName = "Dawson" },
                new User(){ FirstName = "Kent", LastName = "Clark" }
            };
 
            users = users.AsQueryable()
                .OrderBy("LastName", System.ComponentModel.ListSortDirection.Ascending)
                .ToList();
 
            Assert.AreEqual("Clark", users[0].LastName);
            Assert.AreEqual("Dawson", users[1].LastName);
            Assert.AreEqual("Patterson", users[2].LastName);
        }
    }
Publicité
Retour à l'accueil
Partager cet article
Repost0
Pour être informé des derniers articles, inscrivez vous :
Commenter cet article