コード例 #1
0
        public static IQueryable <TDb> OrderBy <TDb>(this IQueryable <TDb> source, OrderModel model)
        {
            var x = Expression.Parameter(source.ElementType, "x");

            System.Linq.Expressions.LambdaExpression selector = null;

            if ((model?.ByDistance ?? false))
            {
                var arr =
                    source.ToArray();

                var parseMethod     = typeof(double).GetMethod("Parse", new[] { typeof(string) });
                var dbParameterXstr = Expression.PropertyOrField(x, "Latitude");
                var dbParameterX    =
                    Expression.Call(parseMethod, dbParameterXstr);
                var dbParameterYstr = Expression.PropertyOrField(x, "Longitude");
                var dbParameterY    =
                    Expression.Call(parseMethod, dbParameterYstr);
                var xParameterLocal = Expression.Constant(model.X);
                var yParameterLocal = Expression.Constant(model.Y);
                var xParameter      = Expression.Subtract(dbParameterX, xParameterLocal);
                var yParameter      = Expression.Subtract(dbParameterY, yParameterLocal);
                var xSquared        = Expression.Multiply(xParameter, xParameter);
                var ySquared        = Expression.Multiply(yParameter, yParameter);
                var sum             = Expression.Add(xSquared, ySquared);
                var sqrtMethod      = typeof(Math).GetMethod("Sqrt", new[] { typeof(double) });
                var distance        = Expression.Call(sqrtMethod, sum);
                selector = Expression.Lambda(
                    distance,
                    x);
            }
            else
            {
                selector = Expression.Lambda(Expression.PropertyOrField(x, model.PropertyName), x);
            }


            return
                (source.Provider.CreateQuery <TDb>(
                     Expression.Call(typeof(Queryable), model.IsDes ? "OrderByDescending" : "OrderBy",
                                     new Type[] { source.ElementType, selector.Body.Type },

                                     source.Expression, selector

                                     )));
        }
コード例 #2
0
        public static IQueryable <TDb> OrderBy3 <TDb>(this IQueryable <TDb> source, OrderModel model)
        {
            var x = Expression.Parameter(source.ElementType, "x");

            System.Linq.Expressions.LambdaExpression selector = null;

            if ((model?.ByDistance ?? false))
            {
                var parseMethod     = typeof(double).GetMethod("Parse", new[] { typeof(string) });
                var dbParameterXstr = Expression.PropertyOrField(x, "Latitude");
                var dbParameterX    =
                    Expression.Call(parseMethod, dbParameterXstr);

                var dbParameterYstr = Expression.PropertyOrField(x, "Longitude");
                var dbParameterY    =
                    Expression.Call(parseMethod, dbParameterYstr);

                var xParameterLocal = Expression.Constant(model.X);

                var yParameterLocal = Expression.Constant(model.Y);

                var sqrtMethod = typeof(Math).GetMethod("Sqrt", new[] { typeof(double) });
                var cosMethod  = typeof(Math).GetMethod("Cos", new[] { typeof(double) });
                var asinMethod = typeof(Math).GetMethod("Asin", new[] { typeof(double) });

                var pParameter = Expression.Constant(0.017453292519943295);

                var latSubst         = Expression.Subtract(dbParameterX, xParameterLocal);
                var latSubstP        = Expression.Multiply(latSubst, pParameter);
                var cosLatSubstP     = Expression.Call(cosMethod, latSubstP);
                var cosLatSubstPdiv2 = Expression.Divide(cosLatSubstP, Expression.Constant(2.0));

                var locLatP    = Expression.Multiply(xParameterLocal, pParameter);
                var cosLocLatP = Expression.Call(cosMethod, locLatP);

                var dbLatP    = Expression.Multiply(dbParameterX, pParameter);
                var cosDbLatP = Expression.Call(cosMethod, dbLatP);

                var longSubst                 = Expression.Subtract(dbParameterY, yParameterLocal);
                var longSubstP                = Expression.Multiply(longSubst, pParameter);
                var cosLongSubstP             = Expression.Call(cosMethod, longSubstP);
                var oneSubstCosLongSubstP     = Expression.Subtract(Expression.Constant(1.0), cosLongSubstP);
                var oneSubstCosLongSubstPdiv2 = Expression.Divide(oneSubstCosLongSubstP, Expression.Constant(2.0));

                var mult12 =
                    Expression.Multiply(cosLocLatP, cosDbLatP);
                var mult123 = Expression.Multiply(mult12, oneSubstCosLongSubstPdiv2);

                var res =
                    Expression.Subtract(Expression.Constant(0.5), cosLatSubstPdiv2);
                var res2 =
                    Expression.Add(res, mult123);

                var sqrtRes     = Expression.Call(sqrtMethod, res2);
                var asinSqrtRes = Expression.Call(asinMethod, sqrtRes);
                var distance    = Expression.Multiply(Expression.Constant(12742.0), asinSqrtRes);

                selector = Expression.Lambda(
                    distance,
                    x);
            }
            else
            {
                selector = Expression.Lambda(Expression.PropertyOrField(x, model.PropertyName), x);
            }

            return
                (source.Provider.CreateQuery <TDb>(
                     Expression.Call(typeof(Queryable), model.IsDes ? "OrderByDescending" : "OrderBy",
                                     new Type[] { source.ElementType, selector.Body.Type },

                                     source.Expression, selector

                                     )));
        }
コード例 #3
0
        public static IQueryable <TDb> OrderBy2 <TDb>(this IQueryable <TDb> source, OrderModel model)
        {
            var x = Expression.Parameter(source.ElementType, "x");

            System.Linq.Expressions.LambdaExpression selector = null;

            if ((model?.ByDistance ?? false))
            {
                var parseMethod     = typeof(double).GetMethod("Parse", new[] { typeof(string) });
                var dbParameterXstr = Expression.PropertyOrField(x, "Latitude");
                var dbParameterX    =
                    Expression.Call(parseMethod, dbParameterXstr);

                var dbParameterYstr = Expression.PropertyOrField(x, "Longitude");
                var dbParameterY    =
                    Expression.Call(parseMethod, dbParameterYstr);

                var xParameterLocal = Expression.Constant(model.X);

                var yParameterLocal = Expression.Constant(model.Y);

                var cosMethod  = typeof(Math).GetMethod("Cos", new[] { typeof(double) });
                var sinMethod  = typeof(Math).GetMethod("Sin", new[] { typeof(double) });
                var acosMethod = typeof(Math).GetMethod("Acos", new[] { typeof(double) });

                Expression Sin(Expression target)
                {
                    return(Expression.Call(sinMethod, target));
                }

                Expression Cos(Expression target)
                {
                    return(Expression.Call(cosMethod, target));
                }

                Expression Acos(Expression target)
                {
                    return(Expression.Call(acosMethod, target));
                }

                var baseRadEx = Expression.Multiply(Expression.Constant(Math.PI),
                                                    Expression.Divide(xParameterLocal, Expression.Constant(180.0)));


                var targetRadEx = Expression.Multiply(Expression.Constant(Math.PI),
                                                      Expression.Divide(dbParameterX, Expression.Constant(180.0)));

                var thetaEx = Expression.Subtract(yParameterLocal, dbParameterY);

                var thetaRadEx = Expression.Multiply(Expression.Constant(Math.PI),
                                                     Expression.Divide(thetaEx, Expression.Constant(180.0)));

                var distEx =
                    Add(Mult(Sin(baseRadEx), Sin(thetaRadEx)),
                        Mult(Cos(thetaRadEx), Mult(Cos(baseRadEx), Cos(targetRadEx))));

                var dist2Ex =
                    Acos(distEx);

                var dist3Ex =
                    Div(Mult(dist2Ex, Expression.Constant(180.0)), Expression.Constant(Math.PI));

                var distance =
                    Mult(dist3Ex, Expression.Constant(111.18957696));


                selector = Expression.Lambda(
                    distance,
                    x);
            }
            else
            {
                selector = Expression.Lambda(Expression.PropertyOrField(x, model.PropertyName), x);
            }

            return
                (source.Provider.CreateQuery <TDb>(
                     Expression.Call(typeof(Queryable), model.IsDes ? "OrderByDescending" : "OrderBy",
                                     new Type[] { source.ElementType, selector.Body.Type },

                                     source.Expression, selector

                                     )));
        }