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)); }
// 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)); }
internal static PropagatorResult CreateServerGenSimpleValue( PropagatorFlags flags, object value, CurrentValueRecord record, int recordOrdinal) { return((PropagatorResult) new PropagatorResult.ServerGenSimpleValue(flags, value, record, recordOrdinal)); }
internal static PropagatorResult CreateKeyValue( PropagatorFlags flags, object value, IEntityStateEntry stateEntry, int identifier) { return((PropagatorResult) new PropagatorResult.KeyValue(flags, value, stateEntry, identifier, (PropagatorResult.KeyValue)null)); }
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); } }
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; }
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)); }
internal ServerGenSimpleValue( PropagatorFlags flags, object value, CurrentValueRecord record, int recordOrdinal) : base(flags, value) { this.m_record = record; this.m_recordOrdinal = recordOrdinal; }
/// <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); } }
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; }
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; }
/// <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); }
/// <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)); }
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)); } } }
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()); }
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); }
/// <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; }
internal override PropagatorResult ReplicateResultWithNewFlags( PropagatorFlags flags) { return((PropagatorResult) new PropagatorResult.ServerGenKeyValue(flags, this.m_value, this.StateEntry, this.Identifier, this.RecordOrdinal, this.m_next)); }
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"); }
/// <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; }
/// <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);
internal static PropagatorResult CreateSimpleValue(PropagatorFlags flags, object value) { return(new SimpleValue(flags, value)); }
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); }
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; }
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); }
internal override PropagatorResult ReplicateResultWithNewFlags(PropagatorFlags flags) { return(new ServerGenSimpleValue(flags, m_value, Record, RecordOrdinal)); }
// 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)); }