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); }
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)); }