Что такое эквивалент ObjectQuery.Parameters в DbQuery

У меня есть код, который получает запрос с помощью оператора linq, что делает его DbQuery, а не ObjectQuery, и я добавлял параметры через цикл foreach, используя этот запрос. Но DbQuery не поддерживает параметры. Я знаю, что могу добавить их вручную. Но у меня есть 36 различных параметров в моем операторе SQL. Поэтому мне нужно найти способ добавить параметры.

foreach (var parameter in query.Parameters)
{
    parameters.Add(new System.Data.SqlClient.SqlParameter { ParameterName = parameter.Name, Value = parameter.Value });
}

entities.Database.ExecuteSqlCommand(sql, parameters.ToArray());

Это код, который я использую для параметров.

Мне нужен способ сделать это с помощью DbQuery


person Corey Toolis    schedule 22.05.2013    source источник


Ответы (2)


Вы можете составить DbQuery, добавив к нему выражения. Для этого часто используется следующий шаблон:

IQueryable<MyType> query = dbContext.Set<MyType>();
if (param1 != null)
    query = query.Where(x => x.Property1 == param1);
if (param2 != null)
    query = query.Where(x => x.Property2 == param2);

Не знаю, сработает ли это в вашей ситуации. Если нет, вы всегда можете прибегнуть к ObjectQuery. DbContext — это оболочка вокруг ObjectContext, и вы можете получить последний с помощью ((IObjectContextAdapter)dbContext).ObjectContext. Это отправная точка для создания ObjectQueries.

person Gert Arnold    schedule 22.05.2013
comment
Да, проблема с использованием объектного запроса для меня заключается в том, что для получения запроса я использую эту строку var query= System.Data.Objects.ObjectQuery‹int›.Select(e=›e.BuyerId); и tje Select(e=›e.BuyerId) возвращает тип DbQuery - person Corey Toolis; 23.05.2013

Я создаю метод расширения для получения параметров

public static class ExpressionExtension
{
    public static object[] GetParameters(this Expression expr)
    {
        var fetcher = new ParameterFetcher();
        fetcher.Visit(expr);
        return fetcher.Parameters.ToArray();
    }

    class ParameterFetcher : System.Linq.Expressions.ExpressionVisitor
    {
        public readonly List<object> Parameters = new List<object>();
        protected Stack<string> CallingStringMethod = new Stack<string>();
        protected int Visited = 0;

        protected override Expression VisitMember(MemberExpression node)
        {
            if (Visited > 0)
            {
                Visited--;
            }
            else
            {
                var member = node;
                while (member != null && member.Expression is MemberExpression)
                {
                    member = (MemberExpression)member.Expression;
                    Visited++;
                }

                if (member != null && member.Expression.NodeType == ExpressionType.Constant)
                {
                    var baseType = Nullable.GetUnderlyingType(node.Type) ?? node.Type;

                    if (baseType == typeof(string) || baseType == typeof(Guid) || baseType.IsPrimitive == true)
                    {
                        var objectMember = Expression.Convert(node, typeof(object));
                        var getterLambda = Expression.Lambda<Func<object>>(objectMember);
                        var value = getterLambda.Invoke();

                        if (value != null && CallingStringMethod.Count > 0)
                        {
                            switch (CallingStringMethod.Peek())
                            {
                                case "StartsWith":
                                    value = Convert.ToString(value).Replace("[", "[[]").Replace("_", "[_]").Replace("%", "[%]") + "%";
                                    break;
                                case "Contains":
                                    value = "%" + Convert.ToString(value).Replace("[", "[[]").Replace("_", "[_]").Replace("%", "[%]") + "%";
                                    break;
                                case "EndsWith":
                                    value = "%" + Convert.ToString(value).Replace("[", "[[]").Replace("_", "[_]").Replace("%", "[%]");
                                    break;
                            }
                        }

                        Parameters.Add(value);
                    }
                }
            }

            return base.VisitMember(node);
        }

        protected override Expression VisitMethodCall(MethodCallExpression node)
        {
            if (node != null && node.Method.DeclaringType == typeof(string))
            {
                switch (node.Method.Name)
                {
                    case "StartsWith":
                    case "Contains":
                    case "EndsWith":
                        CallingStringMethod.Push(node.Method.Name);
                        var val = base.VisitMethodCall(node);
                        CallingStringMethod.Pop();
                        return val;
                }
            }
            return base.VisitMethodCall(node);
        }

        protected override Expression VisitParameter(ParameterExpression node)
        {
            return base.VisitParameter(node);
        }
    }
}

использование

....(IQueryable<TEntity> query)
var parameters = query.Expression.GetParameters();
person Steven C    schedule 15.08.2014