예제 #1
0
            internal override Expression VisitMemberAccess(MemberExpression m)
            {
                if (MetaPosition.AreSameMember(m.Member, association.ThisMember.Member))
                {
                    var keyValues = GetKeyValues(Visit(m.Expression), association.ThisKey);
                    return(WhereClauseFromSourceAndKeys(otherSouce, association.OtherKey.ToArray(), keyValues));
                }
                var expression = Visit(m.Expression);

                if (expression != m.Expression)
                {
                    if (expression.Type != m.Expression.Type && m.Member.Name == "Count" && TypeSystem.IsSequenceType(expression.Type))
                    {
                        return(Expression.Call(typeof(Enumerable), "Count", new Type[1]
                        {
                            TypeSystem.GetElementType(expression.Type)
                        }, expression));
                    }
                    return(Expression.MakeMemberAccess(expression, m.Member));
                }
                return(m);
            }
예제 #2
0
        internal static Expression WhereClauseFromSourceAndKeys(Expression source, MetaDataMember[] keyMembers, Expression[] keyValues)
        {
            var        elementType         = TypeSystem.GetElementType(source.Type);
            var        parameterExpression = Expression.Parameter(elementType, "p");
            Expression expression          = null;

            for (var i = 0; i < keyMembers.Length; i++)
            {
                var        metaDataMember = keyMembers[i];
                var        expression2    = (elementType == metaDataMember.Member.DeclaringType) ? parameterExpression : ((Expression)Expression.Convert(parameterExpression, metaDataMember.Member.DeclaringType));
                Expression expression3    = (metaDataMember.Member is FieldInfo) ? Expression.Field(expression2, (FieldInfo)metaDataMember.Member) : Expression.Property(expression2, (PropertyInfo)metaDataMember.Member);
                var        expression4    = keyValues[i];
                if (expression4.Type != expression3.Type)
                {
                    expression4 = Expression.Convert(expression4, expression3.Type);
                }
                Expression expression5 = Expression.Equal(expression3, expression4);
                expression = ((expression != null) ? Expression.And(expression, expression5) : expression5);
            }
            return(Expression.Call(typeof(Enumerable), "Where", new Type[1]
            {
                parameterExpression.Type
            }, source, Expression.Lambda(expression, parameterExpression)));
        }
            internal override SqlNode Visit(SqlNode node)
            {
                if (node == null)
                {
                    return(null);
                }

                sourceExpression = node as SqlExpression;
                if (sourceExpression != null)
                {
                    Type        type   = sourceExpression.ClrType;
                    UnwrapStack unwrap = this.UnwrapSequences;
                    while (unwrap != null)
                    {
                        if (unwrap.Unwrap)
                        {
                            type = TypeSystem.GetElementType(type);
                        }
                        unwrap = unwrap.Last;
                    }
                    sourceType = type;
                }
                if (sourceType != null && TypeSystem.GetNonNullableType(sourceType).IsValueType)
                {
                    return(node); // Value types can't also have a dynamic type.
                }
                if (sourceType != null && TypeSystem.HasIEnumerable(sourceType))
                {
                    return(node); // Sequences can't be polymorphic.
                }

                switch (node.NodeType)
                {
                case SqlNodeType.ScalarSubSelect:
                case SqlNodeType.Multiset:
                case SqlNodeType.Element:
                case SqlNodeType.SearchedCase:
                case SqlNodeType.ClientCase:
                case SqlNodeType.SimpleCase:
                case SqlNodeType.Member:
                case SqlNodeType.DiscriminatedType:
                case SqlNodeType.New:
                case SqlNodeType.FunctionCall:
                case SqlNodeType.MethodCall:
                case SqlNodeType.Convert:     // Object identity does not survive convert. It does survive Cast.
                    // Dig no further.
                    return(node);

                case SqlNodeType.TypeCase:
                    sourceType = ((SqlTypeCase)node).RowType.Type;
                    return(node);

                case SqlNodeType.Link:
                    sourceType = ((SqlLink)node).RowType.Type;
                    return(node);

                case SqlNodeType.Table:
                    sourceType = ((SqlTable)node).RowType.Type;
                    return(node);

                case SqlNodeType.Value:
                    SqlValue val = (SqlValue)node;
                    if (val.Value != null)
                    {
                        // In some cases the ClrType of a Value node may
                        // differ from the actual runtime type of the value.
                        // Therefore, we ensure here that the correct type is set.
                        sourceType = val.Value.GetType();
                    }
                    return(node);
                }
                return(base.Visit(node));
            }