Exemplo n.º 1
0
        protected override IEnumerable <Entity> ExecuteInternal(IDictionary <string, DataSource> dataSources, IQueryExecutionOptions options, IDictionary <string, Type> parameterTypes, IDictionary <string, object> parameterValues)
        {
            var leftSchema          = LeftSource.GetSchema(dataSources, parameterTypes);
            var innerParameterTypes = GetInnerParameterTypes(leftSchema, parameterTypes);

            if (OuterReferences != null)
            {
                if (parameterTypes == null)
                {
                    innerParameterTypes = new Dictionary <string, Type>();
                }
                else
                {
                    innerParameterTypes = new Dictionary <string, Type>(parameterTypes);
                }

                foreach (var kvp in OuterReferences)
                {
                    innerParameterTypes[kvp.Value] = leftSchema.Schema[kvp.Key];
                }
            }

            var rightSchema   = RightSource.GetSchema(dataSources, innerParameterTypes);
            var mergedSchema  = GetSchema(dataSources, parameterTypes, true);
            var joinCondition = JoinCondition?.Compile(mergedSchema, parameterTypes);

            foreach (var left in LeftSource.Execute(dataSources, options, parameterTypes, parameterValues))
            {
                var innerParameters = parameterValues;

                if (OuterReferences != null)
                {
                    if (parameterValues == null)
                    {
                        innerParameters = new Dictionary <string, object>();
                    }
                    else
                    {
                        innerParameters = new Dictionary <string, object>(parameterValues);
                    }

                    foreach (var kvp in OuterReferences)
                    {
                        left.Attributes.TryGetValue(kvp.Key, out var outerValue);
                        innerParameters[kvp.Value] = outerValue;
                    }
                }

                var hasRight = false;

                foreach (var right in RightSource.Execute(dataSources, options, innerParameterTypes, innerParameters))
                {
                    var merged = Merge(left, leftSchema, right, rightSchema);

                    if (joinCondition == null || joinCondition(merged, parameterValues, options))
                    {
                        yield return(merged);
                    }

                    hasRight = true;

                    if (SemiJoin)
                    {
                        break;
                    }
                }

                if (!hasRight && JoinType == QualifiedJoinType.LeftOuter)
                {
                    yield return(Merge(left, leftSchema, null, rightSchema));
                }
            }
        }