2

표현식 방문자가 p => p.SubRelatedEntities.FirstOrDefault(sre => sre.SomeFlag==true).SomePropertyWithRelatedEntity과 같이 (단순화 된) Utility.GetString(MyEntity.SomePropertyWithRelatedEntity)=="abc"과 같은 함수 호출을 대체하려고합니다.즉시 엔티티 프레임 워크에서 대체 된 표현식 노드의 매개 변수를 바인딩하는 방법

그것은 의미

의 데이터 모델과 같은 간다 : MyEntity -> RelatedEntity -> SubRelatedEntity

나는 RelatedEntity에서 몇 가지 규칙에 따라 SubRelatedEntity에서 문자열 값을 반환하기 위해 노력하고있어, 내가하지 모든 사용법에서 전체 필터링 규칙을 다시 작성/복사/붙여 넣기해야합니다. 그게 내 "호출 서명"을 넣는 이유입니다. 그래서 표현의 방문자가 그것을 식별하고 가짜 호출을 Utility.GetString으로 대체하여 복잡한 람다 식으로 바꿀 수 있습니다.

내 표현의 방문자가 같은 것을 포함

public override Expression Visit(Expression node) 
    { 
     if (node == null) 
      return null; 

     Expression result = null; 

     if (node.NodeType == ExpressionType.Call) 
     { 
      MethodCallExpression mce = node as MethodCallExpression; 
      if (mce.Method.DeclaringType == typeof(Utility) && mce.Method.Name == "GetString") 
      { 
       Expression<Func<RelatedEntity, string>> exp = re => re.SubRelatedEntities.FirstOrDefault(sre => sre.SomeFlag == true).SomeStringValue; 
       result = exp.Body; 

      } 
      else 
       result = base.Visit(node); 
     } 
     else 
      result = base.Visit(node); 

     return result; 

    } 

이제 문제는 "SRE"매개 변수가 주입 된 람다 식 호출 할 때 바인드되어 있지 않습니다. 많은 연구가 끝나면 람다 매개 변수를 다른 표현식 방문자로 대체해야하며 특히 새 매개 변수를 검색하여 이전 매개 변수로 대체해야합니다. 그러나 제 상황에서는 "이전 매개 변수"가 없습니다. 생성 된 람다에 어떻게 든 삽입해야하는 표현 인 MyEntity.SomePropertyWithRelatedEntity (예 : 관련된 엔티티로 채워진 속성)이 있습니다.

내 문제가 이해되기를 바랍니다. 통찰력을 가져 주셔서 감사합니다!

답변

3

오랫동안 아무 대답도 얻지 못했고 해결책을 찾기 위해 열심히 노력한 끝에 저는 그것을 결국 해결했습니다 : o)!

새롭게 주입 된 람다 식은 ParameterExpression을 얻습니다.이 매개 변수는 람다를 직접 호출 할 때 사용되는 '도우미'입니다. 따라서 원하지 않는 것은 (따라서 '매개 변수는 ToEnumerable이 호출 됨). 그래서 단서는이 도우미를 원본 표현식으로 바꾸는 전문화 된 ExpressionVisitor를 만드는 것입니다.이 표현식은 대체 할 메소드 호출에 대한 Arguments []에서 사용할 수 있습니다.

매력처럼 작동합니다. 이렇게하면 모든 동일한 LINQ 물건을 항상 작성하는 대신 재사용 가능한 하위 쿼리와 같은 동일한 LINQ 표현식을 재사용 할 수 있습니다. 주목할 것은, 메서드를 호출하는 표현식이 EF에서는 허용되지 않는다는 것인데, Linq2Sql에서는 그것이 작동한다는 것입니다. 또한 제안 된 모든 웹 기사는 더 많은 LINQ 표현식을 함께 구성/병합 할 때 매개 변수 인스턴스 만 바꿉니다. 여기에서 매개 변수를 위조 된 메서드 호출 인수로 대체해야했습니다. 메서드를 호출해서는 안되며, LINQ 하위 쿼리를 넣어야하는 코드 마커를 나타냅니다.

호프는 표현의 나무가 어떻게 구성되는지를 아는 사람에게 도움이 될 것입니다 .--) 결국 간단하고 논리적입니다.

안녕, 솔루션을 게시 할 시간을내어

+0

감사 안드레이 - 많은 감사 – Basic