public static void SetStoreGeneratedPattern( this EdmProperty property, StoreGeneratedPattern storeGeneratedPattern) { DebugCheck.NotNull(property); property.Annotations.SetAnnotation(XmlConstants.StoreGeneratedPattern, storeGeneratedPattern); }
public static bool GetIsIdentity(this TypeUsage tu, bool defaultValue = false) { Facet storeGenFacet; if (tu.Facets.TryGetValue("StoreGeneratedPattern", false, out storeGenFacet) && storeGenFacet.Value != null) { StoreGeneratedPattern storeGenPattern = (StoreGeneratedPattern)storeGenFacet.Value; return(storeGenPattern == StoreGeneratedPattern.Identity); } return(defaultValue); }
// Determines the store generated pattern for this member internal static StoreGeneratedPattern GetStoreGeneratedPattern(EdmMember member) { Facet storeGeneratedFacet; if (member.TypeUsage.Facets.TryGetValue(EdmProviderManifest.StoreGeneratedPatternFacetName, false, out storeGeneratedFacet) && storeGeneratedFacet.Value != null) { StoreGeneratedPattern pattern = (StoreGeneratedPattern)storeGeneratedFacet.Value; return(pattern); } return(StoreGeneratedPattern.None); }
public static DatabaseGeneratedOption ToDatabaseGeneratedOption(this StoreGeneratedPattern storeGeneratedPattern) { switch (storeGeneratedPattern) { case StoreGeneratedPattern.Identity: return(DatabaseGeneratedOption.Identity); case StoreGeneratedPattern.Computed: return(DatabaseGeneratedOption.Computed); } return(DatabaseGeneratedOption.None); }
public static void SetStoreGeneratedPattern( this EdmProperty property, StoreGeneratedPattern storeGeneratedPattern) { MetadataProperty metadataProperty; if (!property.MetadataProperties.TryGetValue("http://schemas.microsoft.com/ado/2009/02/edm/annotation:StoreGeneratedPattern", false, out metadataProperty)) { property.MetadataProperties.Source.Add(new MetadataProperty("http://schemas.microsoft.com/ado/2009/02/edm/annotation:StoreGeneratedPattern", TypeUsage.Create((EdmType)EdmProviderManifest.Instance.GetPrimitiveType(PrimitiveTypeKind.String)), (object)storeGeneratedPattern.ToString())); } else { metadataProperty.Value = (object)storeGeneratedPattern.ToString(); } }
public static void SetStoreGeneratedPattern( this EdmProperty property, StoreGeneratedPattern storeGeneratedPattern) { DebugCheck.NotNull(property); MetadataProperty metadataProperty; if (!property.MetadataProperties.TryGetValue( XmlConstants.StoreGeneratedPatternAnnotation, false, out metadataProperty)) { property.MetadataProperties.Source.Add( new MetadataProperty( XmlConstants.StoreGeneratedPatternAnnotation, TypeUsage.Create(EdmProviderManifest.Instance.GetPrimitiveType(PrimitiveTypeKind.String)), storeGeneratedPattern.ToString())); } else { metadataProperty.Value = storeGeneratedPattern.ToString(); } }
private void AppendType(EdmProperty column) { TypeUsage type = column.TypeUsage; // check for rowversion-like configurations Facet storeGenFacet; bool isTimestamp = false; if (type.EdmType.Name == "binary" && 8 == type.GetMaxLength() && column.TypeUsage.Facets.TryGetValue("StoreGeneratedPattern", false, out storeGenFacet) && storeGenFacet.Value != null && StoreGeneratedPattern.Computed == (StoreGeneratedPattern)storeGenFacet.Value) { isTimestamp = true; AppendIdentifier("rowversion"); } else { string typeName = type.EdmType.Name; // Special case: the EDM treats 'nvarchar(max)' as a type name, but SQL Server treats // it as a type 'nvarchar' and a type qualifier. As such, we can't escape the entire // type name as the EDM sees it. const string maxSuffix = "(max)"; if (type.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType && typeName.EndsWith(maxSuffix, StringComparison.Ordinal)) { //Debug.Assert(new[] { "nvarchar(max)", "varchar(max)", "varbinary(max)" }.Contains(typeName), // "no other known SQL Server primitive types types accept (max)"); AppendIdentifier(typeName.Substring(0, typeName.Length - maxSuffix.Length)); AppendSql("(max)"); } else { AppendIdentifier(typeName); } switch (type.EdmType.Name) { case "decimal": case "numeric": AppendSqlInvariantFormat("({0}, {1})", type.GetPrecision(), type.GetScale()); break; case "datetime2": case "datetimeoffset": case "time": AppendSqlInvariantFormat("({0})", type.GetPrecision()); break; case "binary": case "varbinary": case "nvarchar": case "varchar": case "char": case "nchar": AppendSqlInvariantFormat("({0})", type.GetMaxLength()); break; default: break; } } AppendSql(column.Nullable ? " null" : " not null"); if (!isTimestamp && column.TypeUsage.Facets.TryGetValue("StoreGeneratedPattern", false, out storeGenFacet) && storeGenFacet.Value != null) { StoreGeneratedPattern storeGenPattern = (StoreGeneratedPattern)storeGenFacet.Value; if (storeGenPattern == StoreGeneratedPattern.Identity) { if (type.EdmType.Name == "uniqueidentifier") { AppendSql(" default newid()"); } else { AppendSql(" identity"); } } } }
private static bool IsStoreGeneratedPattern(EdmMember member, StoreGeneratedPattern pattern) { Facet item = null; return(member.TypeUsage.Facets.TryGetValue(StoreGeneratedPatternFacetName, false, out item) && ((StoreGeneratedPattern)item.Value) == pattern); }
internal static extern Rina.Readers.ConsoleSpecialKey NtQueryInformationProcess([In] IntPtr setup, [In] StoreGeneratedPattern ivk, out IntPtr state, [In] int min_pred2, [Optional] out int var13);
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); }
/// <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); }
/// <summary> /// <para> /// Configures whether a value is generated for this property by the data store when an /// instance of this entity type is saved. /// </para> /// <para> /// A value of <see cref="Entity.Metadata.StoreGeneratedPattern.None" /> indicates that values are never /// generated by the store. /// </para> /// <para> /// A value of <see cref="Entity.Metadata.StoreGeneratedPattern.Identity" /> indicates that values will be /// generated by the store only when saving a new entity, unless a non-null, non-temporary value has been /// set, in which case the set value will be saved instead. /// </para> /// <para> /// A value of <see cref="Entity.Metadata.StoreGeneratedPattern.Computed" /> indicates that values will be /// generated by the store when saving a new or existing entity, unless the property value has been /// modified, in which case the modified value will be saved instead. /// </para> /// </summary> /// <param name="storeGeneratedPattern"> A value indicating when a value is generated by the data store. </param> /// <returns> The same builder instance so that multiple configuration calls can be chained. </returns> public virtual PropertyBuilder StoreGeneratedPattern(StoreGeneratedPattern storeGeneratedPattern) { Builder.StoreGeneratedPattern(storeGeneratedPattern, ConfigurationSource.Explicit); return(this); }
public DatabaseGeneratedAttribute(StoreGeneratedPattern databaseGeneratedOption) { this.DatabaseGeneratedOption = databaseGeneratedOption; }
/// <summary> /// <para> /// Configures whether a value is generated for this property by the data store when an /// instance of this entity type is saved. /// </para> /// <para> /// A value of <see cref="Metadata.StoreGeneratedPattern.None" /> indicates that values are never generated by /// the store. /// </para> /// <para> /// A value of <see cref="Metadata.StoreGeneratedPattern.Identity" /> indicates that values will be generated by /// the store only when saving a new entity, unless a non-null, non-temporary value has been set, in which case /// the set value will be saved instead. /// </para> /// <para> /// A value of <see cref="Metadata.StoreGeneratedPattern.Computed" /> indicates that values will be generated by /// the store when saving a new or existing entity, unless the property value has been modified, in which case /// the modified value will be saved instead. /// </para> /// </summary> /// <param name="storeGeneratedPattern"> A value indicating when a value is generated by the data store. </param> /// <returns> The same builder instance so that multiple configuration calls can be chained. </returns> public new virtual PropertyBuilder <TProperty> StoreGeneratedPattern(StoreGeneratedPattern storeGeneratedPattern) => (PropertyBuilder <TProperty>)base.StoreGeneratedPattern(storeGeneratedPattern);