Describes a member reference representing an entity rather than a simple column.
Inheritance: Remotion.Linq.Clauses.Expressions.ExtensionExpression
    public void SetUp ()
    {
      _stageMock = MockRepository.GenerateStrictMock<IMappingResolutionStage>();
      _resolverMock = MockRepository.GenerateStrictMock<IMappingResolver>();
      _context = new MappingResolutionContext();

      _entityIdentityResolver = new EntityIdentityResolver (_stageMock, _resolverMock, _context);

      _entityExpression = SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Cook), primaryKeyType: typeof (int));
      _entityConstantExpression = new SqlEntityConstantExpression (typeof (Cook), new Cook (), Expression.Constant (0));
      _entityRefMemberExpression = new SqlEntityRefMemberExpression (
          SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Kitchen)),
          typeof (Kitchen).GetProperty ("Cook"));
    }
    private Expression GetIdentityExpressionForReferencedEntity (SqlEntityRefMemberExpression expression)
    {
      var optimizedIdentity = _resolver.TryResolveOptimizedIdentity (expression);
      if (optimizedIdentity != null)
        return optimizedIdentity;

      var unresolvedJoinInfo = new UnresolvedJoinInfo (expression.OriginatingEntity, expression.MemberInfo, JoinCardinality.One);
      return _stage.ResolveEntityRefMemberExpression (expression, unresolvedJoinInfo, _context).GetIdentityExpression ();
    }
    public virtual Expression VisitSqlEntityRefMemberExpression (SqlEntityRefMemberExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      if (!_resolveEntityRefMemberExpressions)
        return VisitExtensionExpression (expression);

      var unresolvedJoinInfo = new UnresolvedJoinInfo (expression.OriginatingEntity, expression.MemberInfo, JoinCardinality.One);
      // No revisiting required since this visitor does not handle ISqlEntityExpressions.
      return _stage.ResolveEntityRefMemberExpression (expression, unresolvedJoinInfo, _context);
    }
    public void TryResolveOptimizedMemberExpression_OtherMember ()
    {
      var tableInfo = new ResolvedSimpleTableInfo (typeof (DataContextTestClass.ClassWithOneToOneRelation_ForeignKeySide), "X", "x");

      var originatingEntity = new SqlEntityDefinitionExpression (
          tableInfo.ItemType, tableInfo.TableAlias, null, e => e.GetColumn (typeof (int), "ID", true));

      var relationMember = tableInfo.ItemType.GetProperty ("VirtualSide");
      var entityRefMemberExpression = new SqlEntityRefMemberExpression (originatingEntity, relationMember);

      var identityMember = typeof (DataContextTestClass.ClassWithOneToOneRelation_VirtualSide).GetProperty ("OtherMember");
      var result = _mappingResolver.TryResolveOptimizedMemberExpression (entityRefMemberExpression, identityMember);

      Assert.That (result, Is.Null);
    }
    public void TryResolveOptimizedMemberExpression_IdentityMember_ForeignKeyOnTheLeft ()
    {
      var tableInfo = new ResolvedSimpleTableInfo (typeof (DataContextTestClass.ClassWithOneToOneRelation_ForeignKeySide), "X", "x");

      var originatingEntity = new SqlEntityDefinitionExpression (
          tableInfo.ItemType, tableInfo.TableAlias, null, e => e.GetColumn (typeof (int), "ID", true));

      var relationMember = tableInfo.ItemType.GetProperty ("VirtualSide");
      var entityRefMemberExpression = new SqlEntityRefMemberExpression (originatingEntity, relationMember);

      var identityMember = typeof (DataContextTestClass.ClassWithOneToOneRelation_VirtualSide).GetProperty ("ID");
      var result = _mappingResolver.TryResolveOptimizedMemberExpression (entityRefMemberExpression, identityMember);

      var orderForeignKey = new SqlColumnDefinitionExpression (typeof (int), tableInfo.TableAlias, "VirtualSideID", false);
      SqlExpressionTreeComparer.CheckAreEqualTrees (orderForeignKey, result);
    }
    public void TryResolveOptimizedIdentity_ForeignKeyOnTheRight ()
    {
      var tableInfo = new ResolvedSimpleTableInfo (typeof (DataContextTestClass.ClassWithOneToOneRelation_VirtualSide), "X", "x");
      var originatingEntity = new SqlEntityDefinitionExpression (tableInfo.ItemType, tableInfo.TableAlias, null, e => e);

      var relationMember = tableInfo.ItemType.GetProperty ("ForeignKeySide");
      var entityRefMemberExpression = new SqlEntityRefMemberExpression (originatingEntity, relationMember);

      var result = _mappingResolver.TryResolveOptimizedIdentity (entityRefMemberExpression);

      Assert.That (result, Is.Null);
    }
    public void ResolveMemberExpression_Association()
    {
      var referencedSqlExpression = new SqlEntityDefinitionExpression (typeof (DataContextTestClass.Customer), "c", null, e => e);

      var sqlEntityExpression = new SqlEntityReferenceExpression (typeof (DataContextTestClass.Order), "o", null, referencedSqlExpression);

      var memberInfo = typeof (DataContextTestClass.Order).GetProperty ("Customer");
      var result = _mappingResolver.ResolveMemberExpression (sqlEntityExpression, memberInfo);

      var expectedExpression = new SqlEntityRefMemberExpression (sqlEntityExpression, memberInfo);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedExpression, result);
    }
 Expression ISqlEntityRefMemberExpressionVisitor.VisitSqlEntityRefMemberExpression (SqlEntityRefMemberExpression expression)
 {
   return VisitExtensionExpression (expression);
 }
    public void VisitSqlEntityRefMemberExpression ()
    {
      var memberInfo = typeof (Restaurant).GetProperty ("Cooks");
      var entityExpression = SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Restaurant));
      var expression = new SqlEntityRefMemberExpression (entityExpression, memberInfo);

      SqlPreparationFromExpressionVisitor.AnalyzeFromExpression (
          expression, _stageMock, _generator, _methodCallTransformerProvider, _context, null);
    }
    public void ResolveExpression_ResolvesSqlEntityRefMemberExpressions ()
    {
      // This test proves that the second stage (resolving SqlEntityRefMemberExpressions) is executed.
      var memberInfo = typeof (Cook).GetProperty ("Kitchen");
      var entityExpression = SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Cook));
      var entityRefMemberExpression = new SqlEntityRefMemberExpression (entityExpression, memberInfo);

      var fakeResult = SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Kitchen));
      _stageMock
          .Expect (
              mock => mock.ResolveEntityRefMemberExpression (
                  Arg.Is (entityRefMemberExpression),
                  Arg<UnresolvedJoinInfo>.Matches (
                      i => i.OriginatingEntity == entityExpression && i.MemberInfo == memberInfo && i.Cardinality == JoinCardinality.One),
                  Arg.Is (_mappingResolutionContext)))
          .Return (fakeResult);

      var result = ResolvingExpressionVisitor.ResolveExpression (
          entityRefMemberExpression, _resolverMock, _stageMock, _mappingResolutionContext, _generator);

      Assert.That (result, Is.SameAs (fakeResult));
    }
    public void ResolveExpression_OptimizesEntityRefMemberComparisons ()
    {
      // This test proves that the first stage (without resolving SqlEntityRefMemberExpressions) is executed.
      var memberInfo = typeof (Kitchen).GetProperty ("Cook");
      var entityExpression = SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Kitchen));
      var fakeOptimizedRefIdentity = new SqlColumnDefinitionExpression (typeof (int), "c", "KitchenID", false);
      var entityRefMemberExpression = new SqlEntityRefMemberExpression (entityExpression, memberInfo);
      _resolverMock
          .Stub (stub => stub.TryResolveOptimizedIdentity (entityRefMemberExpression))
          .Return (fakeOptimizedRefIdentity);

      var entity = CreateEntityExpressionWithIdentity (typeof (Cook), typeof (int));
      var binary = Expression.Equal (entityRefMemberExpression, entity);

      var result = ResolvingExpressionVisitor.ResolveExpression (binary, _resolverMock, _stageMock, _mappingResolutionContext, _generator);

      var expected = Expression.Equal (fakeOptimizedRefIdentity, entity.GetIdentityExpression ());
      SqlExpressionTreeComparer.CheckAreEqualTrees (expected, result);
    }
    public Expression TryResolveOptimizedMemberExpression (SqlEntityRefMemberExpression entityRefMemberExpression, MemberInfo memberInfo)
    {
      if (memberInfo.Name == "ID")
        return TryResolveOptimizedIdentity (entityRefMemberExpression);

      return null;
    }
    public Expression TryResolveOptimizedIdentity (SqlEntityRefMemberExpression entityRefMemberExpression)
    {
      if (entityRefMemberExpression.MemberInfo.DeclaringType == typeof (Cook) && entityRefMemberExpression.MemberInfo.Name == "Knife")
        return ResolveMemberExpression (entityRefMemberExpression.OriginatingEntity, typeof (Cook).GetProperty ("KnifeID"));

      // Prepare a join, then check if the foreign key column is on the left side => this is the identity. (Otherwise, return null.)

      var joinInfo =
          ResolveJoinInfo (
              new UnresolvedJoinInfo (entityRefMemberExpression.OriginatingEntity, entityRefMemberExpression.MemberInfo, JoinCardinality.One),
              new UniqueIdentifierGenerator());

      var rightKey = ((BinaryExpression) joinInfo.JoinCondition).Right;
      while (rightKey.NodeType == ExpressionType.Convert)
        rightKey = ((UnaryExpression) rightKey).Operand;

      if (((SqlColumnExpression) rightKey).IsPrimaryKey)
        return ((BinaryExpression) joinInfo.JoinCondition).Left;

      return null;
    }
    public void ResolveEntityRefMemberExpression ()
    {
      var kitchenCookMember = typeof (Kitchen).GetProperty ("Cook");
      var entityExpression = SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Kitchen));
      var entityRefMemberExpression = new SqlEntityRefMemberExpression (entityExpression, kitchenCookMember);
      var unresolvedJoinInfo = SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_KitchenCook();
      var fakeJoinInfo = SqlStatementModelObjectMother.CreateResolvedJoinInfo (typeof (Cook));
      _mappingResolutionContext.AddSqlEntityMapping (entityExpression, SqlStatementModelObjectMother.CreateSqlTable (typeof (Cook)));

      var fakeEntityExpression = SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Cook));

      _resolverMock
          .Expect (
              mock =>
              mock.ResolveJoinInfo (
                  Arg<UnresolvedJoinInfo>.Matches (joinInfo => joinInfo.MemberInfo == kitchenCookMember), Arg<UniqueIdentifierGenerator>.Is.Anything))
          .Return (fakeJoinInfo);

      _resolverMock
          .Expect (
              mock =>
              mock.ResolveSimpleTableInfo (
                  Arg<IResolvedTableInfo>.Is.Anything,
                  Arg<UniqueIdentifierGenerator>.Is.Anything))
          .Return (fakeEntityExpression);

      var result = _stage.ResolveEntityRefMemberExpression (entityRefMemberExpression, unresolvedJoinInfo, _mappingResolutionContext);

      _resolverMock.VerifyAllExpectations();

      Assert.That (result, Is.SameAs (fakeEntityExpression));
      var sqlTable = _mappingResolutionContext.GetSqlTableForEntityExpression (entityRefMemberExpression.OriginatingEntity);
      Assert.That (sqlTable.GetJoin (kitchenCookMember), Is.Not.Null);
      Assert.That (sqlTable.GetJoin (kitchenCookMember).JoinInfo, Is.SameAs (fakeJoinInfo));
    }
    public virtual SqlEntityExpression ResolveEntityRefMemberExpression (SqlEntityRefMemberExpression expression, IJoinInfo joinInfo, IMappingResolutionContext context)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);
      ArgumentUtility.CheckNotNull ("joinInfo", joinInfo);
      ArgumentUtility.CheckNotNull ("context", context);

      var originatingSqlTable = context.GetSqlTableForEntityExpression (expression.OriginatingEntity);
      var join = originatingSqlTable.GetOrAddLeftJoin (joinInfo, expression.MemberInfo);
      join.JoinInfo = ResolveJoinInfo (join.JoinInfo, context);
      var sqlTableReferenceExpression = new SqlTableReferenceExpression (join);
      
      return (SqlEntityExpression) ResolveExpression (sqlTableReferenceExpression, context);
    }
 public void SetUp ()
 {
   _memberInfo = typeof (Cook).GetProperty ("Substitution");
   _entityExpression = SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Cook), null, "c");
   _expression = new SqlEntityRefMemberExpression (_entityExpression, _memberInfo);
 }