private PropagatorResult CreateSimpleResult(
            IEntityStateEntry stateEntry,
            IExtendedDataRecord record,
            ExtractorMetadata.MemberInformation memberInformation,
            int identifier,
            bool isModified,
            int recordOrdinal,
            object value)
        {
            CurrentValueRecord record1 = record as CurrentValueRecord;
            PropagatorFlags    flags   = memberInformation.Flags;

            if (!isModified)
            {
                flags |= PropagatorFlags.Preserve;
            }
            if (-1 != identifier)
            {
                PropagatorResult owner = !memberInformation.IsServerGenerated && !memberInformation.IsForeignKeyMember || record1 == null?PropagatorResult.CreateKeyValue(flags, value, stateEntry, identifier) : PropagatorResult.CreateServerGenKeyValue(flags, value, stateEntry, identifier, recordOrdinal);

                this.m_translator.KeyManager.RegisterIdentifierOwner(owner);
                return(owner);
            }
            if ((memberInformation.IsServerGenerated || memberInformation.IsForeignKeyMember) && record1 != null)
            {
                return(PropagatorResult.CreateServerGenSimpleValue(flags, value, record1, recordOrdinal));
            }
            return(PropagatorResult.CreateSimpleValue(flags, value));
        }
Пример #2
0
 // Effects: returns true iff. the input propagator result has some flag defined in "flags"
 // Requires: input is set
 private static bool HasFlag(PropagatorResult input, PropagatorFlags flags)
 {
     if (null == input)
     {
         return(false);
     }
     return(PropagatorFlags.NoFlags != (flags & input.PropagatorFlags));
 }
Пример #3
0
 internal static PropagatorResult CreateServerGenSimpleValue(
     PropagatorFlags flags,
     object value,
     CurrentValueRecord record,
     int recordOrdinal)
 {
     return((PropagatorResult) new PropagatorResult.ServerGenSimpleValue(flags, value, record, recordOrdinal));
 }
Пример #4
0
 internal static PropagatorResult CreateKeyValue(
     PropagatorFlags flags,
     object value,
     IEntityStateEntry stateEntry,
     int identifier)
 {
     return((PropagatorResult) new PropagatorResult.KeyValue(flags, value, stateEntry, identifier, (PropagatorResult.KeyValue)null));
 }
Пример #5
0
            internal ServerGenSimpleValue(PropagatorFlags flags, object value, CurrentValueRecord record, int recordOrdinal)
                : base(flags, value)
            {
                DebugCheck.NotNull(record);

                m_record        = record;
                m_recordOrdinal = recordOrdinal;
            }
        internal ExtractorMetadata(
            EntitySetBase entitySetBase,
            StructuralType type,
            UpdateTranslator translator)
        {
            this.m_type       = type;
            this.m_translator = translator;
            EntityType      entityType = (EntityType)null;
            Set <EdmMember> set1;
            Set <EdmMember> set2;

            switch (type.BuiltInTypeKind)
            {
            case BuiltInTypeKind.EntityType:
                entityType = (EntityType)type;
                set1       = new Set <EdmMember>((IEnumerable <EdmMember>)entityType.KeyMembers).MakeReadOnly();
                set2       = new Set <EdmMember>((IEnumerable <EdmMember>)((EntitySet)entitySetBase).ForeignKeyDependents.SelectMany <Tuple <AssociationSet, ReferentialConstraint>, EdmProperty>((Func <Tuple <AssociationSet, ReferentialConstraint>, IEnumerable <EdmProperty> >)(fk => (IEnumerable <EdmProperty>)fk.Item2.ToProperties))).MakeReadOnly();
                break;

            case BuiltInTypeKind.RowType:
                set1 = new Set <EdmMember>((IEnumerable <EdmMember>)((RowType)type).Properties).MakeReadOnly();
                set2 = Set <EdmMember> .Empty;
                break;

            default:
                set1 = Set <EdmMember> .Empty;
                set2 = Set <EdmMember> .Empty;
                break;
            }
            IBaseList <EdmMember> structuralMembers = TypeHelpers.GetAllStructuralMembers((EdmType)type);

            this.m_memberMap = new ExtractorMetadata.MemberInformation[structuralMembers.Count];
            for (int ordinal = 0; ordinal < structuralMembers.Count; ++ordinal)
            {
                EdmMember       edmMember        = structuralMembers[ordinal];
                PropagatorFlags flags            = PropagatorFlags.NoFlags;
                int?            entityKeyOrdinal = new int?();
                if (set1.Contains(edmMember))
                {
                    flags |= PropagatorFlags.Key;
                    if (entityType != null)
                    {
                        entityKeyOrdinal = new int?(entityType.KeyMembers.IndexOf(edmMember));
                    }
                }
                if (set2.Contains(edmMember))
                {
                    flags |= PropagatorFlags.ForeignKey;
                }
                if (MetadataHelper.GetConcurrencyMode(edmMember) == ConcurrencyMode.Fixed)
                {
                    flags |= PropagatorFlags.ConcurrencyValue;
                }
                bool isServerGenerated     = this.m_translator.ViewLoader.IsServerGen(entitySetBase, this.m_translator.MetadataWorkspace, edmMember);
                bool isNullConditionMember = this.m_translator.ViewLoader.IsNullConditionMember(entitySetBase, this.m_translator.MetadataWorkspace, edmMember);
                this.m_memberMap[ordinal] = new ExtractorMetadata.MemberInformation(ordinal, entityKeyOrdinal, flags, edmMember, isServerGenerated, isNullConditionMember);
            }
        }
Пример #7
0
            internal KeyValue(PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier, KeyValue next)
                : base(flags, value)
            {
                DebugCheck.NotNull(stateEntry);

                m_stateEntry = stateEntry;
                m_identifier = identifier;
                m_next       = next;
            }
Пример #8
0
 internal static PropagatorResult CreateServerGenKeyValue(
     PropagatorFlags flags,
     object value,
     IEntityStateEntry stateEntry,
     int identifier,
     int recordOrdinal)
 {
     return((PropagatorResult) new PropagatorResult.ServerGenKeyValue(flags, value, stateEntry, identifier, recordOrdinal, (PropagatorResult.KeyValue)null));
 }
Пример #9
0
 internal ServerGenSimpleValue(
     PropagatorFlags flags,
     object value,
     CurrentValueRecord record,
     int recordOrdinal)
     : base(flags, value)
 {
     this.m_record        = record;
     this.m_recordOrdinal = recordOrdinal;
 }
Пример #10
0
            /// <summary>
            /// Supports propagation of preserve and unknown values when evaluating expressions. If any input
            /// to an expression is marked as unknown, the same is true of the result of evaluating
            /// that expression. If all inputs to an expression are marked 'preserve', then the result is also
            /// marked preserve.
            /// </summary>
            /// <param name="result">Result to markup</param>
            /// <param name="inputs">Expressions contributing to the result</param>
            /// <returns>Marked up result.</returns>
            private static PropagatorFlags PropagateUnknownAndPreserveFlags(PropagatorResult result, IEnumerable <PropagatorResult> inputs)
            {
                bool unknown  = false;
                bool preserve = true;
                bool noInputs = true;

                // aggregate all flags on the inputs
                foreach (PropagatorResult input in inputs)
                {
                    noInputs = false;
                    PropagatorFlags inputFlags = input.PropagatorFlags;
                    if (PropagatorFlags.NoFlags != (PropagatorFlags.Unknown & inputFlags))
                    {
                        unknown = true;
                    }
                    if (PropagatorFlags.NoFlags == (PropagatorFlags.Preserve & inputFlags))
                    {
                        preserve = false;
                    }
                }
                if (noInputs)
                {
                    preserve = false;
                }

                if (null != result)
                {
                    // Merge with existing flags
                    PropagatorFlags flags = result.PropagatorFlags;
                    if (unknown)
                    {
                        flags |= PropagatorFlags.Unknown;
                    }
                    if (!preserve)
                    {
                        flags &= ~PropagatorFlags.Preserve;
                    }

                    return(flags);
                }
                else
                {
                    // if there is no input result, create new markup from scratch
                    PropagatorFlags flags = PropagatorFlags.NoFlags;
                    if (unknown)
                    {
                        flags |= PropagatorFlags.Unknown;
                    }
                    if (preserve)
                    {
                        flags |= PropagatorFlags.Preserve;
                    }
                    return(flags);
                }
            }
Пример #11
0
 internal ServerGenKeyValue(
     PropagatorFlags flags,
     object value,
     IEntityStateEntry stateEntry,
     int identifier,
     int recordOrdinal,
     PropagatorResult.KeyValue next)
     : base(flags, value, stateEntry, identifier, next)
 {
     this.m_recordOrdinal = recordOrdinal;
 }
Пример #12
0
 internal KeyValue(
     PropagatorFlags flags,
     object value,
     IEntityStateEntry stateEntry,
     int identifier,
     PropagatorResult.KeyValue next)
     : base(flags, value)
 {
     this.m_stateEntry = stateEntry;
     this.m_identifier = identifier;
     this.m_next       = next;
 }
Пример #13
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);
                }
 internal MemberInformation(
     int ordinal,
     int?entityKeyOrdinal,
     PropagatorFlags flags,
     EdmMember member,
     bool isServerGenerated,
     bool isNullConditionMember)
 {
     this.Ordinal           = ordinal;
     this.EntityKeyOrdinal  = entityKeyOrdinal;
     this.Flags             = flags;
     this.Member            = member;
     this.IsServerGenerated = isServerGenerated;
     this.CheckIsNotNull    = !TypeSemantics.IsNullable(member) && (isNullConditionMember || member.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType);
 }
Пример #15
0
            /// <summary>
            /// Converts a (nullable) bool to an expression.
            /// </summary>
            /// <param name="booleanValue">Result</param>
            /// <param name="inputs">Inputs contributing to the result</param>
            /// <returns>DbExpression</returns>
            private static PropagatorResult ConvertBoolToResult(bool?booleanValue, params PropagatorResult[] inputs)
            {
                object result;

                if (booleanValue.HasValue)
                {
                    result = booleanValue.Value;;
                }
                else
                {
                    result = null;
                }
                PropagatorFlags flags = PropagateUnknownAndPreserveFlags(null, inputs);

                return(PropagatorResult.CreateSimpleValue(flags, result));
            }
Пример #16
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));
                }
            }
        }
Пример #17
0
        public override string ToString()
        {
            var builder = new StringBuilder();

            if (PropagatorFlags.NoFlags != PropagatorFlags)
            {
                builder.Append(PropagatorFlags.ToString()).Append(":");
            }
            if (NullIdentifier != Identifier)
            {
                builder.Append("id").Append(Identifier.ToString(CultureInfo.InvariantCulture)).Append(":");
            }
            if (NullOrdinal != RecordOrdinal)
            {
                builder.Append("ord").Append(RecordOrdinal.ToString(CultureInfo.InvariantCulture)).Append(":");
            }
            if (IsSimple)
            {
                builder.AppendFormat(CultureInfo.InvariantCulture, "{0}", GetSimpleValue());
            }
            else
            {
                if (!Helper.IsRowType(StructuralType))
                {
                    builder.Append(StructuralType.Name).Append(":");
                }
                builder.Append("{");
                var first = true;
                foreach (var memberValue in Helper.PairEnumerations(
                             TypeHelpers.GetAllStructuralMembers(StructuralType), GetMemberValues()))
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        builder.Append(", ");
                    }
                    builder.Append(memberValue.Key.Name).Append("=").Append(memberValue.Value);
                }
                builder.Append("}");
            }
            return(builder.ToString());
        }
Пример #18
0
            internal MemberInformation(int ordinal, int?entityKeyOrdinal, PropagatorFlags flags, EdmMember member, bool isServerGenerated, bool isNullConditionMember)
            {
                Debug.Assert(entityKeyOrdinal.HasValue ==
                             (member.DeclaringType.BuiltInTypeKind == BuiltInTypeKind.EntityType && (flags & PropagatorFlags.Key) == PropagatorFlags.Key),
                             "key ordinal should only be provided if this is an entity key property");

                this.Ordinal           = ordinal;
                this.EntityKeyOrdinal  = entityKeyOrdinal;
                this.Flags             = flags;
                this.Member            = member;
                this.IsServerGenerated = isServerGenerated;
                // in two cases, we must check that a member value is not null:
                // - where the type participates in an isnull condition, nullability constraints must be honored
                // - for complex types, mapping relies on nullability constraint
                // - in other cases, nullability does not impact round trippability so we don't check
                this.CheckIsNotNull = !TypeSemantics.IsNullable(member) &&
                                      (isNullConditionMember || member.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType);
            }
Пример #19
0
            /// <summary>
            /// Returns the result of evaluating a case expression.
            /// </summary>
            /// <param name="node">Case expression node.</param>
            /// <returns>Result of evaluating case expression over the input row for this visitor.</returns>
            public override PropagatorResult Visit(DbCaseExpression node)
            {
                Debug.Assert(null != node, "node is not visited when null");

                int match            = -1;
                int statementOrdinal = 0;

                List <PropagatorResult> inputs = new List <PropagatorResult>();

                foreach (DbExpression when in node.When)
                {
                    PropagatorResult whenResult = Visit(when);
                    inputs.Add(whenResult);

                    bool matches = ConvertResultToBool(whenResult) ?? false; // ternary logic resolution

                    if (matches)
                    {
                        match = statementOrdinal;
                        break;
                    }

                    statementOrdinal++;
                }

                PropagatorResult matchResult;

                if (-1 == match)
                {
                    matchResult = Visit(node.Else);
                }
                else
                {
                    matchResult = Visit(node.Then[match]);
                }
                inputs.Add(matchResult);

                // Clone the result to avoid modifying expressions that may be used elsewhere
                // (design invariant: only set markup for expressions you create)
                PropagatorFlags  resultFlags = PropagateUnknownAndPreserveFlags(matchResult, inputs);
                PropagatorResult result      = matchResult.ReplicateResultWithNewFlags(resultFlags);

                return(result);
            }
 internal static PropagatorResult CreateServerGenKeyValue(
     PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier, int recordOrdinal)
 {
     return new ServerGenKeyValue(flags, value, stateEntry, identifier, recordOrdinal, null);
 }
 internal static PropagatorResult CreateKeyValue(PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier)
 {
     return new KeyValue(flags, value, stateEntry, identifier, null);
 }
            internal KeyValue(PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier, KeyValue next)
                : base(flags, value)
            {
                Debug.Assert(null != stateEntry);

                m_stateEntry = stateEntry;
                m_identifier = identifier;
                m_next = next;
            }
Пример #23
0
 internal override PropagatorResult ReplicateResultWithNewFlags(
     PropagatorFlags flags)
 {
     return((PropagatorResult) new PropagatorResult.ServerGenKeyValue(flags, this.m_value, this.StateEntry, this.Identifier, this.RecordOrdinal, this.m_next));
 }
Пример #24
0
 internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
 {
     return(new SimpleValue(flags, m_value));
 }
 internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
 {
     throw EntityUtil.InternalError(
         EntityUtil.InternalErrorCode.UpdatePipelineResultRequestInvalid, 0, "StructuralValue.ReplicateResultWithNewFlags");
 }
Пример #26
0
        /// <summary>
        /// Determines column/value used to set values for a row.
        /// </summary>
        /// <remarks>
        /// The following columns are not included in the result:
        /// <list>
        /// <item>Keys in non-insert operations (keys are only set for inserts).</item>
        /// <item>Values flagged 'preserve' (these are values the propagator claims are untouched).</item>
        /// <item>Server generated values.</item>
        /// </list>
        /// </remarks>
        /// <param name="target">Expression binding representing the table.</param>
        /// <param name="row">Row containing values to set.</param>
        /// <param name="processor">Context for table.</param>
        /// <param name="insertMode">Determines whether key columns and 'preserve' columns are
        /// omitted from the list.</param>
        /// <param name="outputIdentifiers">Dictionary listing server generated identifiers.</param>
        /// <param name="returning">DbExpression describing result projection for server generated values.</param>
        /// <param name="rowMustBeTouched">Indicates whether the row must be touched
        /// because it produces a value (e.g. computed)</param>
        /// <returns>Column value pairs.</returns>
        private IEnumerable <DbModificationClause> BuildSetClauses(DbExpressionBinding target, PropagatorResult row,
                                                                   PropagatorResult originalRow, TableChangeProcessor processor, bool insertMode, out Dictionary <int, string> outputIdentifiers, out DbExpression returning,
                                                                   ref bool rowMustBeTouched)
        {
            Dictionary <EdmProperty, PropagatorResult>  setClauses         = new Dictionary <EdmProperty, PropagatorResult>();
            List <KeyValuePair <string, DbExpression> > returningArguments = new List <KeyValuePair <string, DbExpression> >();

            outputIdentifiers = new Dictionary <int, string>();

            // Determine which flags indicate a property should be omitted from the set list.
            PropagatorFlags omitMask = insertMode ? PropagatorFlags.NoFlags :
                                       PropagatorFlags.Preserve | PropagatorFlags.Unknown;

            for (int propertyOrdinal = 0; propertyOrdinal < processor.Table.ElementType.Properties.Count; propertyOrdinal++)
            {
                EdmProperty property = processor.Table.ElementType.Properties[propertyOrdinal];

                // Type members and result values are ordinally aligned
                PropagatorResult propertyResult = row.GetMemberValue(propertyOrdinal);

                if (PropagatorResult.NullIdentifier != propertyResult.Identifier)
                {
                    // retrieve principal value
                    propertyResult = propertyResult.ReplicateResultWithNewValue(
                        m_translator.KeyManager.GetPrincipalValue(propertyResult));
                }

                bool omitFromSetList = false;

                Debug.Assert(propertyResult.IsSimple);

                // Determine if this is a key value
                bool isKey = false;
                for (int i = 0; i < processor.KeyOrdinals.Length; i++)
                {
                    if (processor.KeyOrdinals[i] == propertyOrdinal)
                    {
                        isKey = true;
                        break;
                    }
                }

                // check if this value should be omitted
                PropagatorFlags flags = PropagatorFlags.NoFlags;
                if (!insertMode && isKey)
                {
                    // Keys are only set for inserts
                    omitFromSetList = true;
                }
                else
                {
                    // See if this value has been marked up with some context. If so, add the flag information
                    // from the markup. Markup includes information about whether the property is a concurrency value,
                    // whether it is known (it may be a property that is preserved across an update for instance)
                    flags |= propertyResult.PropagatorFlags;
                }

                // Determine if this value is server-generated
                StoreGeneratedPattern genPattern = MetadataHelper.GetStoreGeneratedPattern(property);
                bool isServerGen = genPattern == StoreGeneratedPattern.Computed ||
                                   (insertMode && genPattern == StoreGeneratedPattern.Identity);
                if (isServerGen)
                {
                    DbPropertyExpression propertyExpression = target.Variable.Property(property);
                    returningArguments.Add(new KeyValuePair <string, DbExpression>(property.Name, propertyExpression));

                    // check if this is a server generated identifier
                    int identifier = propertyResult.Identifier;
                    if (PropagatorResult.NullIdentifier != identifier)
                    {
                        if (m_translator.KeyManager.HasPrincipals(identifier))
                        {
                            throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Update_GeneratedDependent(property.Name));
                        }
                        outputIdentifiers.Add(identifier, property.Name);

                        // If this property maps an identifier (in the update pipeline) it may
                        // also be a store key. If so, the pattern had better be "Identity"
                        // since otherwise we're dealing with a mutable key.
                        if (genPattern != StoreGeneratedPattern.Identity &&
                            processor.IsKeyProperty(propertyOrdinal))
                        {
                            throw EntityUtil.NotSupported(System.Data.Entity.Strings.Update_NotSupportedComputedKeyColumn(
                                                              EdmProviderManifest.StoreGeneratedPatternFacetName,
                                                              XmlConstants.Computed,
                                                              XmlConstants.Identity,
                                                              property.Name,
                                                              property.DeclaringType.FullName));
                        }
                    }
                }

                if (PropagatorFlags.NoFlags != (flags & (omitMask)))
                {
                    // column value matches "omit" pattern, therefore should not be set
                    omitFromSetList = true;
                }
                else if (isServerGen)
                {
                    // column value does not match "omit" pattern, but it is server generated
                    // so it cannot be set
                    omitFromSetList = true;

                    // if the row has a modified value overridden by server gen,
                    // it must still be touched in order to retrieve the value
                    rowMustBeTouched = true;
                }

                // make the user is not updating an identity value
                if (!omitFromSetList && !insertMode && genPattern == StoreGeneratedPattern.Identity)
                {
                    //throw the error only if the value actually changed
                    Debug.Assert(originalRow != null, "Updated records should have a original row");
                    PropagatorResult originalPropertyResult = originalRow.GetMemberValue(propertyOrdinal);
                    Debug.Assert(originalPropertyResult.IsSimple, "Server Gen property that is not primitive?");
                    Debug.Assert(propertyResult.IsSimple, "Server Gen property that is not primitive?");

                    if (!ByValueEqualityComparer.Default.Equals(originalPropertyResult.GetSimpleValue(), propertyResult.GetSimpleValue()))
                    {
                        throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.Update_ModifyingIdentityColumn(
                                                              XmlConstants.Identity,
                                                              property.Name,
                                                              property.DeclaringType.FullName));
                    }
                    else
                    {
                        omitFromSetList = true;
                    }
                }

                if (!omitFromSetList)
                {
                    setClauses.Add(property, propertyResult);
                }
            }

            // Construct returning projection
            if (0 < returningArguments.Count)
            {
                returning = DbExpressionBuilder.NewRow(returningArguments);
            }
            else
            {
                returning = null;
            }

            // Construct clauses corresponding to the set clauses
            List <DbModificationClause> result = new List <DbModificationClause>(setClauses.Count);

            foreach (KeyValuePair <EdmProperty, PropagatorResult> setClause in setClauses)
            {
                EdmProperty property = setClause.Key;

                result.Add(new DbSetClause(
                               GeneratePropertyExpression(target, setClause.Key),
                               GenerateValueExpression(setClause.Key, setClause.Value)));
            }

            return(result);
        }
 internal static PropagatorResult CreateSimpleValue(PropagatorFlags flags, object value)
 {
     return new SimpleValue(flags, value);
 }
 internal SimpleValue(PropagatorFlags flags, object value)
 {
     m_flags = flags;
     m_value = value ?? DBNull.Value;
 }
Пример #29
0
 /// <summary>
 ///     Produces a replica of this propagator result with different flags.
 /// </summary>
 /// <param name="flags"> New flags for the result. </param>
 /// <returns> This result with the given flags. </returns>
 internal abstract PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags);
 /// <summary>
 /// Produces a replica of this propagator result with different flags.
 /// </summary>
 /// <param name="flags">New flags for the result.</param>
 /// <returns>This result with the given flags.</returns>
 internal abstract PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags);
Пример #31
0
 internal static PropagatorResult CreateSimpleValue(PropagatorFlags flags, object value)
 {
     return(new SimpleValue(flags, value));
 }
Пример #32
0
 internal SimpleValue(PropagatorFlags flags, object value)
 {
     m_flags = flags;
     m_value = value ?? DBNull.Value;
 }
Пример #33
0
 internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
 {
     return(new ServerGenKeyValue(flags, m_value, StateEntry, Identifier, RecordOrdinal, m_next));
 }
 internal ServerGenKeyValue(
     PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier, int recordOrdinal, KeyValue next)
     : base(flags, value, stateEntry, identifier, next)
 {
     m_recordOrdinal = recordOrdinal;
 }
 internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
 {
     return new SimpleValue(flags, m_value);
 }
 internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
 {
     return new ServerGenKeyValue(flags, m_value, StateEntry, Identifier, RecordOrdinal, m_next);
 }
 internal static PropagatorResult CreateServerGenSimpleValue(
     PropagatorFlags flags, object value, CurrentValueRecord record, int recordOrdinal)
 {
     return new ServerGenSimpleValue(flags, value, record, recordOrdinal);
 }
Пример #38
0
        private IEnumerable <DbModificationClause> BuildSetClauses(
            DbExpressionBinding target,
            PropagatorResult row,
            PropagatorResult originalRow,
            TableChangeProcessor processor,
            bool insertMode,
            out Dictionary <int, string> outputIdentifiers,
            out DbExpression returning,
            ref bool rowMustBeTouched)
        {
            Dictionary <EdmProperty, PropagatorResult>  dictionary       = new Dictionary <EdmProperty, PropagatorResult>();
            List <KeyValuePair <string, DbExpression> > keyValuePairList = new List <KeyValuePair <string, DbExpression> >();

            outputIdentifiers = new Dictionary <int, string>();
            PropagatorFlags propagatorFlags1 = insertMode ? PropagatorFlags.NoFlags : PropagatorFlags.Preserve | PropagatorFlags.Unknown;

            for (int index1 = 0; index1 < processor.Table.ElementType.Properties.Count; ++index1)
            {
                EdmProperty      property = processor.Table.ElementType.Properties[index1];
                PropagatorResult result   = row.GetMemberValue(index1);
                if (-1 != result.Identifier)
                {
                    result = result.ReplicateResultWithNewValue(this.m_translator.KeyManager.GetPrincipalValue(result));
                }
                bool flag1 = false;
                bool flag2 = false;
                for (int index2 = 0; index2 < processor.KeyOrdinals.Length; ++index2)
                {
                    if (processor.KeyOrdinals[index2] == index1)
                    {
                        flag2 = true;
                        break;
                    }
                }
                PropagatorFlags propagatorFlags2 = PropagatorFlags.NoFlags;
                if (!insertMode && flag2)
                {
                    flag1 = true;
                }
                else
                {
                    propagatorFlags2 |= result.PropagatorFlags;
                }
                StoreGeneratedPattern generatedPattern = MetadataHelper.GetStoreGeneratedPattern((EdmMember)property);
                bool flag3 = generatedPattern == StoreGeneratedPattern.Computed || insertMode && generatedPattern == StoreGeneratedPattern.Identity;
                if (flag3)
                {
                    DbPropertyExpression propertyExpression = target.Variable.Property(property);
                    keyValuePairList.Add(new KeyValuePair <string, DbExpression>(property.Name, (DbExpression)propertyExpression));
                    int identifier = result.Identifier;
                    if (-1 != identifier)
                    {
                        if (this.m_translator.KeyManager.HasPrincipals(identifier))
                        {
                            throw new InvalidOperationException(Strings.Update_GeneratedDependent((object)property.Name));
                        }
                        outputIdentifiers.Add(identifier, property.Name);
                        if (generatedPattern != StoreGeneratedPattern.Identity && processor.IsKeyProperty(index1))
                        {
                            throw new NotSupportedException(Strings.Update_NotSupportedComputedKeyColumn((object)"StoreGeneratedPattern", (object)"Computed", (object)"Identity", (object)property.Name, (object)property.DeclaringType.FullName));
                        }
                    }
                }
                if ((propagatorFlags2 & propagatorFlags1) != PropagatorFlags.NoFlags)
                {
                    flag1 = true;
                }
                else if (flag3)
                {
                    flag1            = true;
                    rowMustBeTouched = true;
                }
                if (!flag1 && !insertMode && generatedPattern == StoreGeneratedPattern.Identity)
                {
                    PropagatorResult memberValue = originalRow.GetMemberValue(index1);
                    if (!ByValueEqualityComparer.Default.Equals(memberValue.GetSimpleValue(), result.GetSimpleValue()))
                    {
                        throw new InvalidOperationException(Strings.Update_ModifyingIdentityColumn((object)"Identity", (object)property.Name, (object)property.DeclaringType.FullName));
                    }
                    flag1 = true;
                }
                if (!flag1)
                {
                    dictionary.Add(property, result);
                }
            }
            returning = 0 >= keyValuePairList.Count ? (DbExpression)null : (DbExpression)DbExpressionBuilder.NewRow((IEnumerable <KeyValuePair <string, DbExpression> >)keyValuePairList);
            List <DbModificationClause> modificationClauseList = new List <DbModificationClause>(dictionary.Count);

            foreach (KeyValuePair <EdmProperty, PropagatorResult> keyValuePair in dictionary)
            {
                EdmProperty key = keyValuePair.Key;
                modificationClauseList.Add((DbModificationClause) new DbSetClause(UpdateCompiler.GeneratePropertyExpression(target, keyValuePair.Key), this.GenerateValueExpression(keyValuePair.Key, keyValuePair.Value)));
            }
            return((IEnumerable <DbModificationClause>)modificationClauseList);
        }
            internal ServerGenSimpleValue(PropagatorFlags flags, object value, CurrentValueRecord record, int recordOrdinal)
                : base(flags, value)
            {
                Debug.Assert(null != record);

                m_record = record;
                m_recordOrdinal = recordOrdinal;
            }
Пример #40
0
        internal ExtractorMetadata(EntitySetBase entitySetBase, StructuralType type, UpdateTranslator translator)
        {
            EntityUtil.CheckArgumentNull(entitySetBase, "entitySetBase");
            m_type       = EntityUtil.CheckArgumentNull(type, "type");
            m_translator = EntityUtil.CheckArgumentNull(translator, "translator");

            EntityType      entityType = null;
            Set <EdmMember> keyMembers;
            Set <EdmMember> foreignKeyMembers;

            switch (type.BuiltInTypeKind)
            {
            case BuiltInTypeKind.RowType:
                // for row types (which are actually association end key records in disguise), all members
                // are keys
                keyMembers        = new Set <EdmMember>(((RowType)type).Properties).MakeReadOnly();
                foreignKeyMembers = Set <EdmMember> .Empty;
                break;

            case BuiltInTypeKind.EntityType:
                entityType        = (EntityType)type;
                keyMembers        = new Set <EdmMember>(entityType.KeyMembers).MakeReadOnly();
                foreignKeyMembers = new Set <EdmMember>(((EntitySet)entitySetBase).ForeignKeyDependents
                                                        .SelectMany(fk => fk.Item2.ToProperties)).MakeReadOnly();
                break;

            default:
                keyMembers        = Set <EdmMember> .Empty;
                foreignKeyMembers = Set <EdmMember> .Empty;
                break;
            }

            IBaseList <EdmMember> members = TypeHelpers.GetAllStructuralMembers(type);

            m_memberMap = new MemberInformation[members.Count];
            // for each member, cache expensive to compute metadata information
            for (int ordinal = 0; ordinal < members.Count; ordinal++)
            {
                EdmMember member = members[ordinal];
                // figure out flags for this member
                PropagatorFlags flags            = PropagatorFlags.NoFlags;
                int?            entityKeyOrdinal = default(int?);

                if (keyMembers.Contains(member))
                {
                    flags |= PropagatorFlags.Key;
                    if (null != entityType)
                    {
                        entityKeyOrdinal = entityType.KeyMembers.IndexOf(member);
                    }
                }
                if (foreignKeyMembers.Contains(member))
                {
                    flags |= PropagatorFlags.ForeignKey;
                }


                if (MetadataHelper.GetConcurrencyMode(member) == ConcurrencyMode.Fixed)
                {
                    flags |= PropagatorFlags.ConcurrencyValue;
                }

                // figure out whether this member is mapped to any server generated
                // columns in the store
                bool isServerGenerated = m_translator.ViewLoader.IsServerGen(entitySetBase, m_translator.MetadataWorkspace, member);

                // figure out whether member nullability is used as a condition in mapping
                bool isNullConditionMember = m_translator.ViewLoader.IsNullConditionMember(entitySetBase, m_translator.MetadataWorkspace, member);

                // add information about this member
                m_memberMap[ordinal] = new MemberInformation(ordinal, entityKeyOrdinal, flags, member, isServerGenerated, isNullConditionMember);
            }
        }
 internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
 {
     return new ServerGenSimpleValue(flags, m_value, Record, RecordOrdinal);
 }
            internal MemberInformation(
                int ordinal, int? entityKeyOrdinal, PropagatorFlags flags, EdmMember member, bool isServerGenerated,
                bool isNullConditionMember)
            {
                Debug.Assert(
                    entityKeyOrdinal.HasValue ==
                    (member.DeclaringType.BuiltInTypeKind == BuiltInTypeKind.EntityType
                     && (flags & PropagatorFlags.Key) == PropagatorFlags.Key),
                    "key ordinal should only be provided if this is an entity key property");

                Ordinal = ordinal;
                EntityKeyOrdinal = entityKeyOrdinal;
                Flags = flags;
                Member = member;
                IsServerGenerated = isServerGenerated;
                // in two cases, we must check that a member value is not null:
                // - where the type participates in an isnull condition, nullability constraints must be honored
                // - for complex types, mapping relies on nullability constraint
                // - in other cases, nullability does not impact round trippability so we don't check
                CheckIsNotNull = !TypeSemantics.IsNullable(member) &&
                                 (isNullConditionMember || member.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType);
            }
Пример #43
0
 internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
 {
     return(new ServerGenSimpleValue(flags, m_value, Record, RecordOrdinal));
 }
Пример #44
0
 internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags)
 {
     throw EntityUtil.InternalError(
               EntityUtil.InternalErrorCode.UpdatePipelineResultRequestInvalid, 0, "StructuralValue.ReplicateResultWithNewFlags");
 }
Пример #45
0
 // Effects: returns true iff. the input propagator result has some flag defined in "flags"
 // Requires: input is set
 private static bool HasFlag(PropagatorResult input, PropagatorFlags flags)
 {
     if (null == input) { return false; }
     return (PropagatorFlags.NoFlags != (flags & input.PropagatorFlags));
 }