protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { return(methodCall.IsQueryable("LoadWith")); }
static IEnumerable <MemberInfo> GetAssociations(ExpressionBuilder builder, Expression expression) { MemberInfo lastMember = null; for (;;) { switch (expression.NodeType) { case ExpressionType.Parameter: if (lastMember == null) { goto default; } yield break; case ExpressionType.Call: { if (lastMember == null) { goto default; } var cexpr = (MethodCallExpression)expression; var expr = cexpr.Object; if (expr == null) { if (cexpr.Arguments.Count == 0) { goto default; } expr = cexpr.Arguments[0]; } if (expr.NodeType != ExpressionType.MemberAccess) { goto default; } var member = ((MemberExpression)expr).Member; var mtype = member.GetMemberType(); if (lastMember.ReflectedTypeEx() != mtype.GetItemType()) { goto default; } expression = expr; break; } case ExpressionType.MemberAccess: { var mexpr = (MemberExpression)expression; var member = lastMember = mexpr.Member; var attr = builder.MappingSchema.GetAttribute <AssociationAttribute>(member); if (attr == null) { throw new LinqToDBException( string.Format("Member '{0}' is not an association.", expression)); } yield return(member); expression = mexpr.Expression; break; } case ExpressionType.ArrayIndex: { expression = ((BinaryExpression)expression).Left; break; } case ExpressionType.Extension: { if (expression is GetItemExpression) { expression = ((GetItemExpression)expression).Expression; break; } goto default; } default: { throw new LinqToDBException( string.Format("Expression '{0}' is not an association.", expression)); } } } }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); var collectionSelector = (LambdaExpression)methodCall.Arguments[1].Unwrap(); var resultSelector = (LambdaExpression)methodCall.Arguments[2].Unwrap(); if (!sequence.SelectQuery.GroupBy.IsEmpty) { sequence = new SubQueryContext(sequence); } var context = new SelectManyContext(buildInfo.Parent, collectionSelector, sequence); var expr = collectionSelector.Body.Unwrap(); var collectionInfo = new BuildInfo(context, expr, new SelectQuery()); var collection = builder.BuildSequence(collectionInfo); var leftJoin = collection is DefaultIfEmptyBuilder.DefaultIfEmptyContext; var sql = collection.SelectQuery; var sequenceTables = new HashSet <ISqlTableSource>(sequence.SelectQuery.From.Tables[0].GetTables()); var newQuery = null != new QueryVisitor().Find(sql, e => e == collectionInfo.SelectQuery); var crossApply = null != new QueryVisitor().Find(sql, e => e.ElementType == QueryElementType.TableSource && sequenceTables.Contains((ISqlTableSource)e) || e.ElementType == QueryElementType.SqlField && sequenceTables.Contains(((SqlField)e).Table) || e.ElementType == QueryElementType.Column && sequenceTables.Contains(((SelectQuery.Column)e).Parent)); if (collection is JoinBuilder.GroupJoinSubQueryContext) { var groupJoin = ((JoinBuilder.GroupJoinSubQueryContext)collection).GroupJoin; groupJoin.SelectQuery.From.Tables[0].Joins[0].JoinType = SelectQuery.JoinType.Inner; groupJoin.SelectQuery.From.Tables[0].Joins[0].IsWeak = false; } if (!newQuery) { context.Collection = new SubQueryContext(collection, sequence.SelectQuery, false); return(new SelectContext(buildInfo.Parent, resultSelector, sequence, context)); } if (!crossApply) { if (!leftJoin) { context.Collection = new SubQueryContext(collection, sequence.SelectQuery, true); return(new SelectContext(buildInfo.Parent, resultSelector, sequence, context)); } else { var join = SelectQuery.OuterApply(sql); sequence.SelectQuery.From.Tables[0].Joins.Add(join.JoinedTable); context.Collection = new SubQueryContext(collection, sequence.SelectQuery, false); return(new SelectContext(buildInfo.Parent, resultSelector, sequence, context)); } } if (collection is TableBuilder.TableContext) { var table = (TableBuilder.TableContext)collection; var join = table.SqlTable.TableArguments != null && table.SqlTable.TableArguments.Length > 0 ? (leftJoin ? SelectQuery.OuterApply(sql) : SelectQuery.CrossApply(sql)) : (leftJoin ? SelectQuery.LeftJoin(sql) : SelectQuery.InnerJoin(sql)); join.JoinedTable.Condition.Conditions.AddRange(sql.Where.SearchCondition.Conditions); join.JoinedTable.CanConvertApply = false; sql.Where.SearchCondition.Conditions.Clear(); var collectionParent = collection.Parent as TableBuilder.TableContext; // Association. // if (collectionParent != null && collectionInfo.IsAssociationBuilt) { var ts = (SelectQuery.TableSource) new QueryVisitor().Find(sequence.SelectQuery.From, e => { if (e.ElementType == QueryElementType.TableSource) { var t = (SelectQuery.TableSource)e; return(t.Source == collectionParent.SqlTable); } return(false); }); ts.Joins.Add(join.JoinedTable); } else { sequence.SelectQuery.From.Tables[0].Joins.Add(join.JoinedTable); } context.Collection = new SubQueryContext(collection, sequence.SelectQuery, false); return(new SelectContext(buildInfo.Parent, resultSelector, sequence, context)); } else { var join = leftJoin ? SelectQuery.OuterApply(sql) : SelectQuery.CrossApply(sql); sequence.SelectQuery.From.Tables[0].Joins.Add(join.JoinedTable); context.Collection = new SubQueryContext(collection, sequence.SelectQuery, false); return(new SelectContext(buildInfo.Parent, resultSelector, sequence, context)); } }
protected override SequenceConvertInfo Convert( ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo, ParameterExpression param) { return(null); }
protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { return(methodCall.IsQueryable("Contains") && methodCall.Arguments.Count == 2); }
protected override IBuildContext BuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { var sequence = builder.BuildSequence(new BuildInfo(buildInfo, methodCall.Arguments[0])); return(new ContainsContext(buildInfo.Parent, methodCall, sequence)); }
protected override bool CanBuildMethodCall(ExpressionBuilder builder, MethodCallExpression methodCall, BuildInfo buildInfo) { return(methodCall.IsQueryable("Where", "Having")); }
public bool IsSequence(ExpressionBuilder builder, BuildInfo buildInfo) { return(builder.IsSequence(new BuildInfo(buildInfo, ((MethodCallExpression)buildInfo.Expression).Arguments[0]))); }
public SequenceConvertInfo Convert(ExpressionBuilder builder, BuildInfo buildInfo, ParameterExpression param) { return(null); }
public IBuildContext BuildSequence(ExpressionBuilder builder, BuildInfo buildInfo) { var call = (MethodCallExpression)buildInfo.Expression; return(new Context(builder.BuildSequence(new BuildInfo(buildInfo, call.Arguments[0])))); }
public bool CanBuild(ExpressionBuilder builder, BuildInfo buildInfo) { var call = buildInfo.Expression as MethodCallExpression; return(call != null && call.Method.Name == "GetContext"); }