lundi 11 mai 2015

order by lambda expression with expression trees in C#

My requirement is to order table according to a column in runtime. So I went through the path of parameter expression. I am able to achieve it when all the columns are present in single table. Here is my piece of code:

My requirement is to order table according to the buildStatusOrder during run time:

 List<BuildStatusEnum> buildStatusOrder = new List<BuildStatusEnum>
            {
                BuildStatusEnum.h,
                BuildStatusEnum.f,
                BuildStatusEnum.a
            };

            ParameterExpression parameterExpression = Expression.Parameter(typeof(companyQueue));
            MemberExpression memberExpression = Expression.PropertyOrField(parameterExpression, "buildStatusID");
            MemberExpression valueExpression = Expression.Property(memberExpression, "Value");

            Expression orderByExpression = Expression.Constant(buildStatusOrder.Count);
            for (int statusIndex = buildStatusOrder.Count - 1; statusIndex >= 0; statusIndex--)
            {
                ConstantExpression constantExpression = Expression.Constant((int)buildStatusOrder[statusIndex]);
                ConstantExpression indexConstantExpression = Expression.Constant(statusIndex);
                BinaryExpression equalExpression = Expression.Equal(valueExpression, constantExpression);

                orderByExpression = Expression.Condition(equalExpression, indexConstantExpression, orderByExpression);
            }

            MemberExpression hasValueExpression = Expression.Property(memberExpression, "HasValue");
            ConditionalExpression nullCheckExpression = Expression.Condition(hasValueExpression, orderByExpression, Expression.Constant(buildStatusOrder.Count));

            var orderByLambda = Expression.Lambda<Func<companyQueue, int>>(nullCheckExpression, parameterExpression);

            using (KapowContext context = new KapowContext())
            {
                var queue = context.companyQueues

                        .Where(cq => cq.u.s.cq.userID == Utilities.Authentication.UserId)
                         .Where(cq => buildStatusOrder.Contains((BuildStatusEnum)cq.u.s.cq.buildStatusID))
                         .OrderBy(o => o.u.se.segmentId)
                         .ThenBy(orderByLambda)

This works fine. I have to display an additional column. It is from another table. So I joined tables. My lambda expression now looks like this:

 var queue = context.companyQueues
                         .Join(context.abcd, cq => cq.robotID, r => r.robotId, (cq, r) => new { cq, r })
                         .Join(context.efgh, s => s.r.segmentId, se => se.segmentId, (s, se) => new { s, se })
                         .Join(context.hijk, u => u.s.cq.userID, us => us.userID, (u, us) => new { u, us })

                        .Where(cq => cq.u.s.cq.userID == Utilities.Authentication.UserId)
                         .Where(cq => buildStatusOrder.Contains((BuildStatusEnum)cq.u.s.cq.buildStatusID))
                        .OrderBy(orderByLambda)

Now my orderbyLambda is not working. I am getting the following error:

'System.Linq.Queryable.ThenBy<TSource,TKey>(System.Linq.IOrderedQueryable<TSource>, System.Linq.Expressions.Expression<System.Func<TSource,TKey>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.





Aucun commentaire:

Enregistrer un commentaire