예제 #1
0
                /// <summary>
                /// Construct a new placeholder with the shape of the given placeholder. Key values are
                /// injected into the resulting place holder and default values are substituted with
                /// either propagator constants or progagator nulls depending on the mode established
                /// by the <paramref name="mode"/> flag.
                /// </summary>
                /// <remarks>
                /// The key is essentially an array of values. The key map indicates that for a particular
                /// placeholder an expression (keyMap.Keys) corresponds to some ordinal in the key array.
                /// </remarks>
                /// <param name="placeholder">Placeholder to clone</param>
                /// <param name="key">Key to substitute</param>
                /// <param name="placeholderKey">Key elements in the placeholder (ordinally aligned with 'key')</param>
                /// <param name="mode">Mode of operation.</param>
                /// <param name="translator">Translator context.</param>
                /// <returns>Cloned placeholder with key values</returns>
                internal static PropagatorResult Populate(PropagatorResult placeholder, CompositeKey key,
                                                          CompositeKey placeholderKey, PopulateMode mode, UpdateTranslator translator)
                {
                    EntityUtil.CheckArgumentNull(placeholder, "placeholder");
                    EntityUtil.CheckArgumentNull(key, "key");
                    EntityUtil.CheckArgumentNull(placeholderKey, "placeholderKey");
                    EntityUtil.CheckArgumentNull(translator, "translator");

                    // Figure out which flags to apply to generated elements.
                    bool            isNull   = mode == PopulateMode.NullModified || mode == PopulateMode.NullPreserve;
                    bool            preserve = mode == PopulateMode.NullPreserve || mode == PopulateMode.Unknown;
                    PropagatorFlags flags    = PropagatorFlags.NoFlags;

                    if (!isNull)
                    {
                        flags |= PropagatorFlags.Unknown;
                    }                                                  // only null values are known
                    if (preserve)
                    {
                        flags |= PropagatorFlags.Preserve;
                    }

                    PropagatorResult result = placeholder.Replace(node =>
                    {
                        // See if this is a key element
                        int keyIndex = -1;
                        for (int i = 0; i < placeholderKey.KeyComponents.Length; i++)
                        {
                            if (placeholderKey.KeyComponents[i] == node)
                            {
                                keyIndex = i;
                                break;
                            }
                        }

                        if (keyIndex != -1)
                        {
                            // Key value.
                            return(key.KeyComponents[keyIndex]);
                        }
                        else
                        {
                            // for simple entries, just return using the markup context for this
                            // populator
                            object value = isNull ? null : node.GetSimpleValue();
                            return(PropagatorResult.CreateSimpleValue(flags, value));
                        }
                    });

                    return(result);
                }
예제 #2
0
            /// <summary>
            /// Produce a tuple containing joined rows.
            /// </summary>
            /// <param name="left">Left row.</param>
            /// <param name="right">Right row.</param>
            /// <param name="leftKey">Key used to join left element.</param>
            /// <param name="rightKey">Key used to join right element.</param>
            /// <param name="result">Result change node; used for type information.</param>
            /// <returns>Result of joining the input rows.</returns>
            private PropagatorResult CreateResultTuple(Tuple <CompositeKey, PropagatorResult> left, Tuple <CompositeKey, PropagatorResult> right, ChangeNode result)
            {
                // using ref compare to avoid triggering value based
                CompositeKey leftKey  = left.Item1;
                CompositeKey rightKey = right.Item1;
                Dictionary <PropagatorResult, PropagatorResult> map = null;

                if (!object.ReferenceEquals(null, leftKey) &&
                    !object.ReferenceEquals(null, rightKey) &&
                    !object.ReferenceEquals(leftKey, rightKey))
                {
                    // Merge key values from the left and the right (since they're equal, there's a possibility we'll
                    // project values only from the left or the right hand side and lose important context.)
                    CompositeKey mergedKey = leftKey.Merge(m_parent.m_updateTranslator.KeyManager, rightKey);
                    // create a dictionary so that we can replace key values with merged key values (carrying context
                    // from both sides)
                    map = new Dictionary <PropagatorResult, PropagatorResult>();
                    for (int i = 0; i < leftKey.KeyComponents.Length; i++)
                    {
                        map[leftKey.KeyComponents[i]]  = mergedKey.KeyComponents[i];
                        map[rightKey.KeyComponents[i]] = mergedKey.KeyComponents[i];
                    }
                }

                PropagatorResult[] joinRecordValues = new PropagatorResult[2];
                joinRecordValues[0] = left.Item2;
                joinRecordValues[1] = right.Item2;
                PropagatorResult join = PropagatorResult.CreateStructuralValue(joinRecordValues, (StructuralType)result.ElementType.EdmType, false);

                // replace with merged key values as appropriate
                if (null != map)
                {
                    PropagatorResult replacement;
                    join = join.Replace(original => map.TryGetValue(original, out replacement) ? replacement : original);
                }

                return(join);
            }
                /// <summary>
                /// Construct a new placeholder with the shape of the given placeholder. Key values are
                /// injected into the resulting place holder and default values are substituted with
                /// either propagator constants or progagator nulls depending on the mode established
                /// by the <paramref name="mode"/> flag.
                /// </summary>
                /// <remarks>
                /// The key is essentially an array of values. The key map indicates that for a particular
                /// placeholder an expression (keyMap.Keys) corresponds to some ordinal in the key array.
                /// </remarks>
                /// <param name="placeholder">Placeholder to clone</param>
                /// <param name="key">Key to substitute</param>
                /// <param name="placeholderKey">Key elements in the placeholder (ordinally aligned with 'key')</param>
                /// <param name="mode">Mode of operation.</param>
                /// <param name="translator">Translator context.</param>
                /// <returns>Cloned placeholder with key values</returns>
                internal static PropagatorResult Populate(PropagatorResult placeholder, CompositeKey key, 
                    CompositeKey placeholderKey, PopulateMode mode, UpdateTranslator translator)
                {
                    EntityUtil.CheckArgumentNull(placeholder, "placeholder");
                    EntityUtil.CheckArgumentNull(key, "key");
                    EntityUtil.CheckArgumentNull(placeholderKey, "placeholderKey");
                    EntityUtil.CheckArgumentNull(translator, "translator");

                    // Figure out which flags to apply to generated elements.
                    bool isNull = mode == PopulateMode.NullModified || mode == PopulateMode.NullPreserve;
                    bool preserve = mode == PopulateMode.NullPreserve || mode == PopulateMode.Unknown;
                    PropagatorFlags flags = PropagatorFlags.NoFlags;
                    if (!isNull) { flags |= PropagatorFlags.Unknown; } // only null values are known
                    if (preserve) { flags |= PropagatorFlags.Preserve; }

                    PropagatorResult result = placeholder.Replace(node =>
                        {
                            // See if this is a key element
                            int keyIndex = -1;
                            for (int i = 0; i < placeholderKey.KeyComponents.Length; i++)
                            {
                                if (placeholderKey.KeyComponents[i] == node)
                                {
                                    keyIndex = i;
                                    break;
                                }
                            }

                            if (keyIndex != -1)
                            {
                                // Key value.
                                return key.KeyComponents[keyIndex];
                            }
                            else
                            {
                                // for simple entries, just return using the markup context for this
                                // populator
                                object value = isNull ? null : node.GetSimpleValue();
                                return PropagatorResult.CreateSimpleValue(flags, value);
                            }
                        });
                    
                    return result;
                }
                /// <summary>
                /// Construct a new placeholder with the shape of the given placeholder. Key values are
                /// injected into the resulting place holder and default values are substituted with
                /// either propagator constants or progagator nulls depending on the mode established
                /// by the <paramref name="mode"/> flag.
                /// </summary>
                /// <remarks>
                /// The key is essentially an array of values. The key map indicates that for a particular
                /// placeholder an expression (keyMap.Keys) corresponds to some ordinal in the key array.
                /// </remarks>
                /// <param name="placeholder">Placeholder to clone</param>
                /// <param name="key">Key to substitute</param>
                /// <param name="placeholderKey">Key elements in the placeholder (ordinally aligned with 'key')</param>
                /// <param name="mode">Mode of operation.</param>
                /// <returns>Cloned placeholder with key values</returns>
                internal static PropagatorResult Populate(
                    PropagatorResult placeholder, CompositeKey key,
                    CompositeKey placeholderKey, PopulateMode mode)
                {
                    //Contract.Requires(placeholder != null);
                    //Contract.Requires(key != null);
                    //Contract.Requires(placeholderKey != null);

                    // Figure out which flags to apply to generated elements.
                    var isNull = mode == PopulateMode.NullModified || mode == PopulateMode.NullPreserve;
                    var preserve = mode == PopulateMode.NullPreserve || mode == PopulateMode.Unknown;
                    var flags = PropagatorFlags.NoFlags;
                    if (!isNull)
                    {
                        flags |= PropagatorFlags.Unknown;
                    } // only null values are known
                    if (preserve)
                    {
                        flags |= PropagatorFlags.Preserve;
                    }

                    var result = placeholder.Replace(
                        node =>
                            {
                                // See if this is a key element
                                var keyIndex = -1;
                                for (var i = 0; i < placeholderKey.KeyComponents.Length; i++)
                                {
                                    if (placeholderKey.KeyComponents[i] == node)
                                    {
                                        keyIndex = i;
                                        break;
                                    }
                                }

                                if (keyIndex != -1)
                                {
                                    // Key value.
                                    return key.KeyComponents[keyIndex];
                                }
                                else
                                {
                                    // for simple entries, just return using the markup context for this
                                    // populator
                                    var value = isNull ? null : node.GetSimpleValue();
                                    return PropagatorResult.CreateSimpleValue(flags, value);
                                }
                            });

                    return result;
                }