public override Expression VisitMemberAccess(MemberExpression m) { if (MetaPosition.AreSameMember(m.Member, this.association.ThisMember.Member)) { Expression[] keyValues = GetKeyValues(this.Visit(m.Expression), this.association.ThisKey); return(Translator.WhereClauseFromSourceAndKeys(this.otherSouce, this.association.OtherKey.ToArray <MetaDataMember>(), keyValues)); } Expression expression = this.Visit(m.Expression); if (expression == m.Expression) { return(m); } if (((expression.Type != m.Expression.Type) && (m.Member.Name == "Count")) && TypeSystem.IsSequenceType(expression.Type)) { return(Expression.Call(typeof(Enumerable), "Count", new Type[] { TypeSystem.GetElementType(expression.Type) }, new Expression[] { expression })); } return(Expression.MakeMemberAccess(expression, m.Member)); }
internal static Expression WhereClauseFromSourceAndKeys(Expression source, MetaDataMember[] keyMembers, Expression[] keyValues) { Type elementType = TypeSystem.GetElementType(source.Type); ParameterExpression expression = Expression.Parameter(elementType, "p"); Expression left = null; for (int i = 0; i < keyMembers.Length; i++) { MetaDataMember member = keyMembers[i]; Expression expression3 = (elementType == member.Member.DeclaringType) ? ((Expression)expression) : ((Expression)Expression.Convert(expression, member.Member.DeclaringType)); Expression expression4 = (member.Member is FieldInfo) ? Expression.Field(expression3, (FieldInfo)member.Member) : Expression.Property(expression3, (PropertyInfo)member.Member); Expression expression5 = keyValues[i]; if (expression5.Type != expression4.Type) { expression5 = Expression.Convert(expression5, expression4.Type); } Expression right = Expression.Equal(expression4, expression5); left = (left != null) ? Expression.And(left, right) : right; } return(Expression.Call(typeof(Enumerable), "Where", new Type[] { expression.Type }, new Expression[] { source, Expression.Lambda(left, new ParameterExpression[] { expression }) })); }
private static Type GetClrType(SqlNode node) { SqlTableValuedFunctionCall call = node as SqlTableValuedFunctionCall; if (call != null) { return(call.RowType.Type); } SqlExpression expression = node as SqlExpression; if (expression != null) { if (TypeSystem.IsSequenceType(expression.ClrType)) { return(TypeSystem.GetElementType(expression.ClrType)); } return(expression.ClrType); } SqlSelect select = node as SqlSelect; if (select != null) { return(select.Selection.ClrType); } SqlTable table = node as SqlTable; if (table != null) { return(table.RowType.Type); } SqlUnion union = node as SqlUnion; if (union == null) { throw Error.UnexpectedNode(node.NodeType); } return(union.GetClrType()); }