public IQueryable <IGrouping <TRet, T> > GroupWith <TRet>(IQueryable <T> q, string propertyName)
        {
            var ex = Expressions.PropertyExpression <T, TRet>(propertyName);

            if (ex == null)
            {
                throw new Exception($"Property {propertyName} does not exist in type {typeof(T).GetType().FullName}");
            }
            return(q.GroupBy(ex));
        }
        public IQueryable <T> SortWith(IQueryable <T> q, string propertyName, SortDir dir)
        {
            PropertyInfo prop = typeof(T).GetProperty(propertyName);

            if (prop == null)
            {
                return(q);
            }

            if (prop.PropertyType == typeof(string))
            {
                var exp = Expressions.PropertyExpression <T, string>(propertyName);
                q = q.SortWith(exp, dir);
            }
            else if (prop.PropertyType == typeof(double))
            {
                var exp = Expressions.PropertyExpression <T, double>(propertyName);
                q = q.SortWith(exp, dir);
            }
            else if (prop.PropertyType == typeof(double?))
            {
                var exp = Expressions.PropertyExpression <T, double?>(propertyName);
                q = q.SortWith(exp, dir);
            }
            else if (prop.PropertyType.IsDecimalType())
            {
                var exp = Expressions.PropertyExpression <T, decimal>(propertyName);
                q = q.SortWith(exp, dir);
            }
            else if (prop.PropertyType.IsDecimalType(true))
            {
                var exp = Expressions.PropertyExpression <T, decimal?>(propertyName);
                q = q.SortWith(exp, dir);
            }
            else if (prop.PropertyType.IsIntgerType())
            {
                var exp = Expressions.PropertyExpression <T, long>(propertyName);
                q = q.SortWith(exp, dir);
            }
            else if (prop.PropertyType.IsIntgerType(true))
            {
                var exp = Expressions.PropertyExpression <T, long?>(propertyName);
                q = q.SortWith(exp, dir);
            }
            else if (prop.PropertyType == typeof(DateTime))
            {
                var exp = Expressions.PropertyExpression <T, DateTime>(propertyName);
                q = q.SortWith(exp, dir);
            }
            else if (prop.PropertyType == typeof(DateTime?))
            {
                var exp = Expressions.PropertyExpression <T, DateTime?>(propertyName);
                q = q.SortWith(exp, dir);
            }
            else
            {
                var exp = Expressions.Property <T>(propertyName);
                q = q.SortWith(exp, dir);
            }
            return(q);
        }