2016-08-04 3 views
1

Oracle.ManagedDataAccess.Client 드라이버로 실행되는 쿼리가 기본 쿼리가 실행되는 경우에도 결과를 반환하는 데 몇 분이 걸리는 EF 6 코드의 비정상적인 문제를 해결했습니다. 2ms.변수의 상수를 사용하여 람다 식을 동적으로 생성

var result = users.Where(u => u.username == varUserName).FirstOrDefault(); 

내가 람다 함수의 상수와 같은 일에 쿼리를 대체하지만 경우 반환하는 데 몇 분 정도 걸릴 수 있습니다이 쿼리, 그것은 즉시 실행 : 다음 예제 쿼리는 것

var result = users.Where(u => u.username == "testUsername").FirstOrDefault(); 

내가 매개 변수화 SQL 쿼리를 작성 할 수 있습니다,이 문제를 해결하려면, 아니면 수동으로 적절한 람다 식 트리 생성 할 수 있습니다

var userParam = Expression.Parameter(typeof(Entity.User), "user"); 
var userNameField = Expression.Property(userParam, "username"); 
var userNameConstant = Expression.Constant(varUserName, typeof(string)); 
var equalUserName = Expression.Equal(userNameField, userNameConstant); 
var lambda = Expression.Lambda<Func<Entity.User, bool>>(equalUserName, new ParameterExpression[] { userParam }); 
var result = users.Where(lambda).FirstOrDefault(); 

이 일 때문에를 그것은 질문을 구걸 : 쉽게 변수에 대한 참조 대신에 변수가 직접 상수로 포함되는 결과 람다 표현 나무를 쉽게 생성하는 방법은 무엇입니까?

예를 들어,이 같은 일이 이상적 일 것이다 :

var lambdaExpression = (u => u.username == varUserName).ReplaceVariablesWithConstants(); 
+2

당신이 의미하지 않았 뭔가처럼 아마 될 것 varUserName, typeof (string)); ' –

+0

나는 확실히 그랬다. 감사합니다. @JeroenvanLangen – fabspro

답변

3

이 같은 ConstantExpression 회원 평가하는 : (`VAR userNameConstant = Expression.Constant :

public static class ExpressionUtils 
{ 
    public static Expression<TDelegate> ReplaceVariablesWithConstants<TDelegate>(this Expression<TDelegate> source) 
    { 
     return source.Update(
      new ReplaceVariablesWithConstantsVisitor().Visit(source.Body), 
      source.Parameters); 
    } 

    class ReplaceVariablesWithConstantsVisitor : ExpressionVisitor 
    { 
     protected override Expression VisitMember(MemberExpression node) 
     { 
      var expression = Visit(node.Expression); 
      if (expression is ConstantExpression) 
      { 
       var variable = ((ConstantExpression)expression).Value; 
       var value = node.Member is FieldInfo ? 
        ((FieldInfo)node.Member).GetValue(variable) : 
        ((PropertyInfo)node.Member).GetValue(variable); 
       return Expression.Constant(value, node.Type); 
      } 
      return node.Update(expression); 
     } 
    } 
} 
+0

대단히 감사합니다. 나는 여기에서 나의 해결 방법을 개발할 수있을 것이라고 확신한다. – fabspro

1

그것은 좀 어렵다. ExpressionsTree를 ExpressionsVisitor으로 수정해야합니다. 그것은 ExpressionVisitor 비교적 쉽게 수행 할 수 있습니다

var lambdaExpression = ReplaceVariablesWithConstants(u => u.username == varUserName); 
+0

대단히 감사합니다. 귀하의 MSDN 링크를 다른 답변과 함께하면 내 문제가 해결됩니다! – fabspro

관련 문제