public OrderByNode <T> ParseOrderBy(string expression)
        {
            OrderByNode <T> newNode = null;
            List <string>   fields  = Regex.Split(expression, fieldSeparator)?.ToList();

            if (fields?.Any() == true)
            {
                int seq = 1;
                fields.ForEach(o =>
                {
                    var parts = Regex.Split(o, orderBySeparator);
                    if (parts.Length <= 2)
                    {
                        string field     = parts[0];
                        string direction = (parts.Length == 2) ? parts[1] : "asc";
                        Type t           = typeof(T);
                        var propInfo     = t.GetProperty(field, System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
                        if (propInfo == null)
                        {
                            throw new ArgumentException($"Property <{field}> not found for <{t.Name}> in $orderby.");
                        }

                        newNode = new OrderByNode <T>
                        {
                            Sequence     = seq,
                            PropertyName = propInfo.Name,
                            Direction    = (string.Compare(direction, "asc", true) == 0) ? OrderByDirectionType.Ascending : OrderByDirectionType.Descending
                        };
                    }
                });
            }
            return(newNode);
        }
        public void Parse(string expression)
        {
            if (string.IsNullOrEmpty(expression))
            {
                throw new ArgumentNullException(expression);
            }

            List <string> fields = Regex.Split(expression, fieldSeparator)?.ToList();

            if (fields?.Any() == true)
            {
                int seq = 1;
                fields.ForEach(o =>
                {
                    var parts = Regex.Split(o, orderBySeparator);
                    if (parts.Length <= 2)
                    {
                        string field     = parts[0];
                        string direction = (parts.Length == 2) ? parts[1] : "asc";
                        Type t           = typeof(T);
                        var propInfo     = t.GetProperty(field, System.Reflection.BindingFlags.IgnoreCase | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
                        if (propInfo == null)
                        {
                            throw new ArgumentException($"Property <{field}> not found for <{t.Name}> in $orderby.");
                        }

                        var newNode = new OrderByNode <T>
                        {
                            Sequence     = seq,
                            PropertyName = propInfo.Name,
                            Direction    = (string.Compare(direction, "asc", true) == 0) ? OrderByDirectionType.Ascending : OrderByDirectionType.Descending
                        };

                        CreateExpression(newNode);
                        OrderByNodes.Add(newNode);
                        seq++;
                    }
                });
            }

            var rootNode = OrderByNodes.FirstOrDefault();

            if (rootNode != null)
            {
                RootExpression = rootNode.Expression.Compile();
                Direction      = rootNode.Direction;
            }
        }
        private void CreateExpression(OrderByNode <T> node)
        {
            if (!string.IsNullOrWhiteSpace(node?.PropertyName))
            {
                var        param  = Expression.Parameter(typeof(T), "p");
                var        parts  = node.PropertyName.Split('.');
                Expression parent = param;
                foreach (var part in parts)
                {
                    parent = Expression.Property(parent, part);
                }

                if (parent.Type.IsValueType)
                {
                    var converted = Expression.Convert(parent, typeof(object));
                    node.Expression = Expression.Lambda <Func <T, object> >(converted, param);
                }
                else
                {
                    node.Expression = Expression.Lambda <Func <T, object> >(parent, param);
                }
            }
        }