// Walks through all parameter bindings in the function mapping and binds the parameters to the
            // requested properties of the given state entry.
            private void BindFunctionParameters(UpdateTranslator translator, ExtractedStateEntry stateEntry, StorageModificationFunctionMapping functionMapping, FunctionUpdateCommand command, Dictionary <AssociationEndMember, IEntityStateEntry> currentReferenceEnds, Dictionary <AssociationEndMember, IEntityStateEntry> originalReferenceEnds)
            {
                // bind all parameters
                foreach (StorageModificationFunctionParameterBinding parameterBinding in functionMapping.ParameterBindings)
                {
                    PropagatorResult result;

                    // extract value
                    if (null != parameterBinding.MemberPath.AssociationSetEnd)
                    {
                        // find the relationship entry corresponding to the navigation
                        AssociationEndMember endMember = parameterBinding.MemberPath.AssociationSetEnd.CorrespondingAssociationEndMember;
                        IEntityStateEntry    relationshipEntry;
                        bool hasTarget = parameterBinding.IsCurrent
                            ? currentReferenceEnds.TryGetValue(endMember, out relationshipEntry)
                            : originalReferenceEnds.TryGetValue(endMember, out relationshipEntry);
                        if (!hasTarget)
                        {
                            if (endMember.RelationshipMultiplicity == RelationshipMultiplicity.One)
                            {
                                string entitySetName      = stateEntry.Source.EntitySet.Name;
                                string associationSetName = parameterBinding.MemberPath.AssociationSetEnd.ParentAssociationSet.Name;
                                throw EntityUtil.Update(Strings.Update_MissingRequiredRelationshipValue(entitySetName, associationSetName),
                                                        null,
                                                        command.GetStateEntries(translator));
                            }
                            else
                            {
                                result = PropagatorResult.CreateSimpleValue(PropagatorFlags.NoFlags, null);
                            }
                        }
                        else
                        {
                            // get the actual value
                            PropagatorResult relationshipResult = parameterBinding.IsCurrent ?
                                                                  translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(relationshipEntry, ModifiedPropertiesBehavior.AllModified) :
                                                                  translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(relationshipEntry, ModifiedPropertiesBehavior.AllModified);
                            PropagatorResult endResult   = relationshipResult.GetMemberValue(endMember);
                            EdmProperty      keyProperty = (EdmProperty)parameterBinding.MemberPath.Members[0];
                            result = endResult.GetMemberValue(keyProperty);
                        }
                    }
                    else
                    {
                        // walk through the member path to find the appropriate propagator results
                        result = parameterBinding.IsCurrent ? stateEntry.Current : stateEntry.Original;
                        for (int i = parameterBinding.MemberPath.Members.Count; i > 0;)
                        {
                            --i;
                            EdmMember member = parameterBinding.MemberPath.Members[i];
                            result = result.GetMemberValue(member);
                        }
                    }

                    // create DbParameter
                    command.SetParameterValue(result, parameterBinding, translator);
                }
                // Add rows affected parameter
                command.RegisterRowsAffectedParameter(functionMapping.RowsAffectedParameter);
            }
Пример #2
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);
                }
Пример #3
0
            // Find "sanctioned" default value
            private static void GetPropagatorResultForPrimitiveType(PrimitiveType primitiveType, out PropagatorResult result)
            {
                object            value;
                PrimitiveTypeKind primitiveTypeKind = primitiveType.PrimitiveTypeKind;

                if (!s_typeDefaultMap.TryGetValue(primitiveTypeKind, out value))
                {
                    // If none exists, default to lowest common denominator for constants
                    value = default(byte);
                }

                // Return a new constant expression flagged as unknown since the value is only there for
                // show. (Not entirely for show, because null constraints may require a value for a record,
                // whether that record is a placeholder or not).
                result = PropagatorResult.CreateSimpleValue(PropagatorFlags.NoFlags, value);
            }
Пример #4
0
        private PropagatorResult CreateSimpleResult(IEntityStateEntry stateEntry, IExtendedDataRecord record, MemberInformation memberInformation,
                                                    int identifier, bool isModified, int recordOrdinal, object value)
        {
            CurrentValueRecord updatableRecord = record as CurrentValueRecord;

            // construct flags for the value, which is needed for complex type and simple members
            PropagatorFlags flags = memberInformation.Flags;

            if (!isModified)
            {
                flags |= PropagatorFlags.Preserve;
            }
            if (PropagatorResult.NullIdentifier != identifier)
            {
                // construct a key member
                PropagatorResult result;
                if ((memberInformation.IsServerGenerated || memberInformation.IsForeignKeyMember) && null != updatableRecord)
                {
                    result = PropagatorResult.CreateServerGenKeyValue(flags, value, stateEntry, identifier, recordOrdinal);
                }
                else
                {
                    result = PropagatorResult.CreateKeyValue(flags, value, stateEntry, identifier);
                }

                // we register the entity as the "owner" of an identity so that back-propagation can succeed
                // (keys can only be back-propagated to entities, not association ends). It also allows us
                // to walk to the entity state entry in case of exceptions, since the state entry propagated
                // through the stack may be eliminated in a project above a join.
                m_translator.KeyManager.RegisterIdentifierOwner(result);

                return(result);
            }
            else
            {
                if ((memberInformation.IsServerGenerated || memberInformation.IsForeignKeyMember) && null != updatableRecord)
                {
                    // note: we only produce a server gen result when
                    return(PropagatorResult.CreateServerGenSimpleValue(flags, value, updatableRecord, recordOrdinal));
                }
                else
                {
                    return(PropagatorResult.CreateSimpleValue(flags, value));
                }
            }
        }