Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Map / Update / Internal / ExtractorMetadata.cs / 1305376 / ExtractorMetadata.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Data.Metadata.Edm; using System.Collections; using System.Collections.Generic; using System.Data.Common.Utils; using System.Data.Objects; using System.Diagnostics; using System.Data.Common; using System.Linq; using System.Data.Entity; namespace System.Data.Mapping.Update.Internal { internal enum ModifiedPropertiesBehavior { ////// Indicates that all properties are modified. Used for added and deleted entities and for /// modified complex type sub-records. /// AllModified, ////// Indicates that no properties are modified. Used for unmodified complex type sub-records. /// NoneModified, ////// Indicates that some properties are modified. Used for modified entities. /// SomeModified, } ////// Encapsulates metadata information relevant to update for records extracted from /// the entity state manager, such as concurrency flags and key information. /// internal class ExtractorMetadata { 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; SetkeyMembers; Set 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 (((RowType)type).Properties).MakeReadOnly(); foreignKeyMembers = Set .Empty; break; case BuiltInTypeKind.EntityType: entityType = (EntityType)type; keyMembers = new Set (entityType.KeyMembers).MakeReadOnly(); foreignKeyMembers = new Set (((EntitySet)entitySetBase).ForeignKeyDependents .SelectMany(fk => fk.Item2.ToProperties)).MakeReadOnly(); break; default: keyMembers = Set .Empty; foreignKeyMembers = Set .Empty; break; } IBaseList 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); } } private readonly MemberInformation[] m_memberMap; private readonly StructuralType m_type; private readonly UpdateTranslator m_translator; /// /// Requires: record must have correct type for this metadata instance. /// Populates a new /// state manager entry containing value (used for error reporting) /// Record containing value (used to find the actual value) /// Indicates whether we are reading current or original values. /// Entity key for the state entry. Must be set for entity records. /// Ordinal of Member for which to retrieve a value. /// modified (must be ordinally aligned with the type). Null indicates all members are modified. /// Indicates how to determine whether a property is modified. ///object representing a member of a record matching the /// type of this extractor. Given a record and a member, this method wraps the value of the member /// in a PropagatorResult. This operation can be performed efficiently by this class, which knows /// important stuff about the type being extracted. /// Propagator result describing this member value. internal PropagatorResult RetrieveMember(IEntityStateEntry stateEntry, IExtendedDataRecord record, bool useCurrentValues, EntityKey key, int ordinal, ModifiedPropertiesBehavior modifiedPropertiesBehavior) { MemberInformation memberInformation = m_memberMap[ordinal]; // get identifier value int identifier; if (memberInformation.IsKeyMember) { // retrieve identifier for this key member Debug.Assert(null != (object)key, "entities must have keys, and only entity members are marked IsKeyMember by " + "the metadata wrapper"); int keyOrdinal = memberInformation.EntityKeyOrdinal.Value; identifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(key, keyOrdinal, ((EntityType)m_type).KeyMembers.Count); } else if (memberInformation.IsForeignKeyMember) { identifier = m_translator.KeyManager.GetKeyIdentifierForMember(key, record.GetName(ordinal), useCurrentValues); } else { identifier = PropagatorResult.NullIdentifier; } // determine if the member is modified bool isModified = modifiedPropertiesBehavior == ModifiedPropertiesBehavior.AllModified || (modifiedPropertiesBehavior == ModifiedPropertiesBehavior.SomeModified && stateEntry.ModifiedProperties != null && stateEntry.ModifiedProperties[memberInformation.Ordinal]); // determine member value Debug.Assert(record.GetName(ordinal) == memberInformation.Member.Name, "expect record to present properties in metadata order"); if (memberInformation.CheckIsNotNull && record.IsDBNull(ordinal)) { throw EntityUtil.Update(Strings.Update_NullValue(record.GetName(ordinal)), null, stateEntry); } object value = record.GetValue(ordinal); // determine what kind of member this is // entityKey (association end) EntityKey entityKey = value as EntityKey; if (null != (object)entityKey) { return CreateEntityKeyResult(stateEntry, entityKey); } // record (nested complex type) IExtendedDataRecord nestedRecord = value as IExtendedDataRecord; if (null != nestedRecord) { // for structural types, we track whether the entire complex type value is modified or not var nestedModifiedPropertiesBehavior = isModified ? ModifiedPropertiesBehavior.AllModified : ModifiedPropertiesBehavior.NoneModified; UpdateTranslator translator = m_translator; return ExtractResultFromRecord(stateEntry, isModified, nestedRecord, useCurrentValues, translator, nestedModifiedPropertiesBehavior); } // simple value (column/property value) return CreateSimpleResult(stateEntry, record, memberInformation, identifier, isModified, ordinal, value); } // Note that this is called only for association ends. Entities have key values inline. private PropagatorResult CreateEntityKeyResult(IEntityStateEntry stateEntry, EntityKey entityKey) { // get metadata for key EntityType entityType = entityKey.GetEntitySet(m_translator.MetadataWorkspace).ElementType; RowType keyRowType = entityType.GetKeyRowType(m_translator.MetadataWorkspace); ExtractorMetadata keyMetadata = m_translator.GetExtractorMetadata(stateEntry.EntitySet, keyRowType); int keyMemberCount = keyRowType.Properties.Count; PropagatorResult[] keyValues = new PropagatorResult[keyMemberCount]; for (int ordinal = 0; ordinal < keyRowType.Properties.Count; ordinal++) { EdmMember keyMember = keyRowType.Properties[ordinal]; // retrieve information about this key value MemberInformation keyMemberInformation = keyMetadata.m_memberMap[ordinal]; int keyIdentifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(entityKey, ordinal, keyRowType.Properties.Count); object keyValue = null; if (entityKey.IsTemporary) { // If the EntityKey is temporary, we need to retrieve the appropriate // key value from the entity itself (or in this case, the IEntityStateEntry). IEntityStateEntry entityEntry = stateEntry.StateManager.GetEntityStateEntry(entityKey); Debug.Assert(entityEntry.State == EntityState.Added, "The corresponding entry for a temp EntityKey should be in the Added State."); keyValue = entityEntry.CurrentValues[keyMember.Name]; } else { // Otherwise, we extract the value from within the EntityKey. keyValue = entityKey.FindValueByName(keyMember.Name); } Debug.Assert(keyValue != null, "keyValue should've been retrieved."); // construct propagator result keyValues[ordinal] = PropagatorResult.CreateKeyValue( keyMemberInformation.Flags, keyValue, stateEntry, keyIdentifier); // see UpdateTranslator.Identifiers for information on key identifiers and ordinals } return PropagatorResult.CreateStructuralValue(keyValues, keyMetadata.m_type, false); } 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); } } } ////// Converts a record to a propagator result /// /// state manager entry containing the record /// Indicates whether the root element is modified (i.e., whether the type has changed) /// Record to convert /// Indicates whether we are retrieving current or original values. /// Translator for session context; registers new metadata for the record type if none /// exists /// Indicates how to determine whether a property is modified. ///Result corresponding to the given record internal static PropagatorResult ExtractResultFromRecord(IEntityStateEntry stateEntry, bool isModified, IExtendedDataRecord record, bool useCurrentValues, UpdateTranslator translator, ModifiedPropertiesBehavior modifiedPropertiesBehavior) { StructuralType structuralType = (StructuralType)record.DataRecordInfo.RecordType.EdmType; ExtractorMetadata metadata = translator.GetExtractorMetadata(stateEntry.EntitySet, structuralType); EntityKey key = stateEntry.EntityKey; PropagatorResult[] nestedValues = new PropagatorResult[record.FieldCount]; for (int ordinal = 0; ordinal < nestedValues.Length; ordinal++) { nestedValues[ordinal] = metadata.RetrieveMember(stateEntry, record, useCurrentValues, key, ordinal, modifiedPropertiesBehavior); } return PropagatorResult.CreateStructuralValue(nestedValues, structuralType, isModified); } private class MemberInformation { ////// Gets ordinal of the member. /// internal readonly int Ordinal; ////// Gets key ordinal for primary key member (null if not a primary key). /// internal readonly int? EntityKeyOrdinal; ////// Gets propagator flags for the member, excluding the 'Preserve' flag /// which can only be set in context. /// internal readonly PropagatorFlags Flags; ////// Indicates whether this is a key member. /// internal bool IsKeyMember { get { return PropagatorFlags.Key == (Flags & PropagatorFlags.Key); } } ////// Indicates whether this is a foreign key member. /// internal bool IsForeignKeyMember { get { return PropagatorFlags.ForeignKey == (Flags & PropagatorFlags.ForeignKey); } } ////// Indicates whether this value is server generated. /// internal readonly bool IsServerGenerated; ////// Indicates whether non-null values are supported for this member. /// internal readonly bool CheckIsNotNull; ////// Gets the member described by this wrapper. /// internal readonly EdmMember Member; 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); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Data.Metadata.Edm; using System.Collections; using System.Collections.Generic; using System.Data.Common.Utils; using System.Data.Objects; using System.Diagnostics; using System.Data.Common; using System.Linq; using System.Data.Entity; namespace System.Data.Mapping.Update.Internal { internal enum ModifiedPropertiesBehavior { ////// Indicates that all properties are modified. Used for added and deleted entities and for /// modified complex type sub-records. /// AllModified, ////// Indicates that no properties are modified. Used for unmodified complex type sub-records. /// NoneModified, ////// Indicates that some properties are modified. Used for modified entities. /// SomeModified, } ////// Encapsulates metadata information relevant to update for records extracted from /// the entity state manager, such as concurrency flags and key information. /// internal class ExtractorMetadata { 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; SetkeyMembers; Set 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 (((RowType)type).Properties).MakeReadOnly(); foreignKeyMembers = Set .Empty; break; case BuiltInTypeKind.EntityType: entityType = (EntityType)type; keyMembers = new Set (entityType.KeyMembers).MakeReadOnly(); foreignKeyMembers = new Set (((EntitySet)entitySetBase).ForeignKeyDependents .SelectMany(fk => fk.Item2.ToProperties)).MakeReadOnly(); break; default: keyMembers = Set .Empty; foreignKeyMembers = Set .Empty; break; } IBaseList 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); } } private readonly MemberInformation[] m_memberMap; private readonly StructuralType m_type; private readonly UpdateTranslator m_translator; /// /// Requires: record must have correct type for this metadata instance. /// Populates a new /// state manager entry containing value (used for error reporting) /// Record containing value (used to find the actual value) /// Indicates whether we are reading current or original values. /// Entity key for the state entry. Must be set for entity records. /// Ordinal of Member for which to retrieve a value. /// modified (must be ordinally aligned with the type). Null indicates all members are modified. /// Indicates how to determine whether a property is modified. ///object representing a member of a record matching the /// type of this extractor. Given a record and a member, this method wraps the value of the member /// in a PropagatorResult. This operation can be performed efficiently by this class, which knows /// important stuff about the type being extracted. /// Propagator result describing this member value. internal PropagatorResult RetrieveMember(IEntityStateEntry stateEntry, IExtendedDataRecord record, bool useCurrentValues, EntityKey key, int ordinal, ModifiedPropertiesBehavior modifiedPropertiesBehavior) { MemberInformation memberInformation = m_memberMap[ordinal]; // get identifier value int identifier; if (memberInformation.IsKeyMember) { // retrieve identifier for this key member Debug.Assert(null != (object)key, "entities must have keys, and only entity members are marked IsKeyMember by " + "the metadata wrapper"); int keyOrdinal = memberInformation.EntityKeyOrdinal.Value; identifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(key, keyOrdinal, ((EntityType)m_type).KeyMembers.Count); } else if (memberInformation.IsForeignKeyMember) { identifier = m_translator.KeyManager.GetKeyIdentifierForMember(key, record.GetName(ordinal), useCurrentValues); } else { identifier = PropagatorResult.NullIdentifier; } // determine if the member is modified bool isModified = modifiedPropertiesBehavior == ModifiedPropertiesBehavior.AllModified || (modifiedPropertiesBehavior == ModifiedPropertiesBehavior.SomeModified && stateEntry.ModifiedProperties != null && stateEntry.ModifiedProperties[memberInformation.Ordinal]); // determine member value Debug.Assert(record.GetName(ordinal) == memberInformation.Member.Name, "expect record to present properties in metadata order"); if (memberInformation.CheckIsNotNull && record.IsDBNull(ordinal)) { throw EntityUtil.Update(Strings.Update_NullValue(record.GetName(ordinal)), null, stateEntry); } object value = record.GetValue(ordinal); // determine what kind of member this is // entityKey (association end) EntityKey entityKey = value as EntityKey; if (null != (object)entityKey) { return CreateEntityKeyResult(stateEntry, entityKey); } // record (nested complex type) IExtendedDataRecord nestedRecord = value as IExtendedDataRecord; if (null != nestedRecord) { // for structural types, we track whether the entire complex type value is modified or not var nestedModifiedPropertiesBehavior = isModified ? ModifiedPropertiesBehavior.AllModified : ModifiedPropertiesBehavior.NoneModified; UpdateTranslator translator = m_translator; return ExtractResultFromRecord(stateEntry, isModified, nestedRecord, useCurrentValues, translator, nestedModifiedPropertiesBehavior); } // simple value (column/property value) return CreateSimpleResult(stateEntry, record, memberInformation, identifier, isModified, ordinal, value); } // Note that this is called only for association ends. Entities have key values inline. private PropagatorResult CreateEntityKeyResult(IEntityStateEntry stateEntry, EntityKey entityKey) { // get metadata for key EntityType entityType = entityKey.GetEntitySet(m_translator.MetadataWorkspace).ElementType; RowType keyRowType = entityType.GetKeyRowType(m_translator.MetadataWorkspace); ExtractorMetadata keyMetadata = m_translator.GetExtractorMetadata(stateEntry.EntitySet, keyRowType); int keyMemberCount = keyRowType.Properties.Count; PropagatorResult[] keyValues = new PropagatorResult[keyMemberCount]; for (int ordinal = 0; ordinal < keyRowType.Properties.Count; ordinal++) { EdmMember keyMember = keyRowType.Properties[ordinal]; // retrieve information about this key value MemberInformation keyMemberInformation = keyMetadata.m_memberMap[ordinal]; int keyIdentifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(entityKey, ordinal, keyRowType.Properties.Count); object keyValue = null; if (entityKey.IsTemporary) { // If the EntityKey is temporary, we need to retrieve the appropriate // key value from the entity itself (or in this case, the IEntityStateEntry). IEntityStateEntry entityEntry = stateEntry.StateManager.GetEntityStateEntry(entityKey); Debug.Assert(entityEntry.State == EntityState.Added, "The corresponding entry for a temp EntityKey should be in the Added State."); keyValue = entityEntry.CurrentValues[keyMember.Name]; } else { // Otherwise, we extract the value from within the EntityKey. keyValue = entityKey.FindValueByName(keyMember.Name); } Debug.Assert(keyValue != null, "keyValue should've been retrieved."); // construct propagator result keyValues[ordinal] = PropagatorResult.CreateKeyValue( keyMemberInformation.Flags, keyValue, stateEntry, keyIdentifier); // see UpdateTranslator.Identifiers for information on key identifiers and ordinals } return PropagatorResult.CreateStructuralValue(keyValues, keyMetadata.m_type, false); } 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); } } } ////// Converts a record to a propagator result /// /// state manager entry containing the record /// Indicates whether the root element is modified (i.e., whether the type has changed) /// Record to convert /// Indicates whether we are retrieving current or original values. /// Translator for session context; registers new metadata for the record type if none /// exists /// Indicates how to determine whether a property is modified. ///Result corresponding to the given record internal static PropagatorResult ExtractResultFromRecord(IEntityStateEntry stateEntry, bool isModified, IExtendedDataRecord record, bool useCurrentValues, UpdateTranslator translator, ModifiedPropertiesBehavior modifiedPropertiesBehavior) { StructuralType structuralType = (StructuralType)record.DataRecordInfo.RecordType.EdmType; ExtractorMetadata metadata = translator.GetExtractorMetadata(stateEntry.EntitySet, structuralType); EntityKey key = stateEntry.EntityKey; PropagatorResult[] nestedValues = new PropagatorResult[record.FieldCount]; for (int ordinal = 0; ordinal < nestedValues.Length; ordinal++) { nestedValues[ordinal] = metadata.RetrieveMember(stateEntry, record, useCurrentValues, key, ordinal, modifiedPropertiesBehavior); } return PropagatorResult.CreateStructuralValue(nestedValues, structuralType, isModified); } private class MemberInformation { ////// Gets ordinal of the member. /// internal readonly int Ordinal; ////// Gets key ordinal for primary key member (null if not a primary key). /// internal readonly int? EntityKeyOrdinal; ////// Gets propagator flags for the member, excluding the 'Preserve' flag /// which can only be set in context. /// internal readonly PropagatorFlags Flags; ////// Indicates whether this is a key member. /// internal bool IsKeyMember { get { return PropagatorFlags.Key == (Flags & PropagatorFlags.Key); } } ////// Indicates whether this is a foreign key member. /// internal bool IsForeignKeyMember { get { return PropagatorFlags.ForeignKey == (Flags & PropagatorFlags.ForeignKey); } } ////// Indicates whether this value is server generated. /// internal readonly bool IsServerGenerated; ////// Indicates whether non-null values are supported for this member. /// internal readonly bool CheckIsNotNull; ////// Gets the member described by this wrapper. /// internal readonly EdmMember Member; 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); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Bezier.cs
- BrowserTree.cs
- XmlNamespaceDeclarationsAttribute.cs
- CodeTypeParameterCollection.cs
- VisualStyleTypesAndProperties.cs
- WebPartConnectionCollection.cs
- WebPartZone.cs
- _TimerThread.cs
- BitmapEffectGeneralTransform.cs
- SqlServer2KCompatibilityCheck.cs
- LogStore.cs
- KoreanLunisolarCalendar.cs
- ResourcePermissionBaseEntry.cs
- IPEndPointCollection.cs
- UserControlParser.cs
- _NTAuthentication.cs
- SettingsPropertyNotFoundException.cs
- TypeSystemProvider.cs
- NativeCppClassAttribute.cs
- RenamedEventArgs.cs
- SiteIdentityPermission.cs
- BaseTemplateCodeDomTreeGenerator.cs
- SmtpReplyReader.cs
- StorageMappingItemLoader.cs
- TextParentUndoUnit.cs
- __ComObject.cs
- XmlDataSourceNodeDescriptor.cs
- WmlObjectListAdapter.cs
- HyperlinkAutomationPeer.cs
- InstanceContextManager.cs
- MemberExpressionHelper.cs
- WMICapabilities.cs
- Schedule.cs
- SqlCacheDependencyDatabase.cs
- DataTrigger.cs
- OdbcCommand.cs
- StylusDownEventArgs.cs
- EventLogTraceListener.cs
- WindowsToolbar.cs
- PagePropertiesChangingEventArgs.cs
- Transform.cs
- UshortList2.cs
- ThicknessKeyFrameCollection.cs
- VirtualDirectoryMapping.cs
- WebReferencesBuildProvider.cs
- Debugger.cs
- DoubleAnimation.cs
- SchemaElement.cs
- SafeLocalMemHandle.cs
- SystemThemeKey.cs
- WorkflowQueuingService.cs
- ModelFunction.cs
- TimelineCollection.cs
- Track.cs
- DataControlLinkButton.cs
- InstancePersistenceEvent.cs
- WsdlExporter.cs
- log.cs
- Propagator.JoinPropagator.JoinPredicateVisitor.cs
- SID.cs
- Range.cs
- CompoundFileReference.cs
- WebReferencesBuildProvider.cs
- ValidatorCollection.cs
- LambdaCompiler.ControlFlow.cs
- SpotLight.cs
- Operators.cs
- AsyncCompletedEventArgs.cs
- Rule.cs
- ToolStripContentPanel.cs
- WorkflowHostingResponseContext.cs
- DateTimeUtil.cs
- Double.cs
- StatusBar.cs
- TemplatePagerField.cs
- DetailsViewRow.cs
- MaterialGroup.cs
- WinFormsSecurity.cs
- RecordManager.cs
- DynamicEntity.cs
- PackageProperties.cs
- PtsHost.cs
- TemplateField.cs
- EventLogTraceListener.cs
- SplitterPanelDesigner.cs
- SymLanguageVendor.cs
- OleDbParameterCollection.cs
- TextEditorLists.cs
- RequestCache.cs
- CommandPlan.cs
- IRCollection.cs
- AssemblyUtil.cs
- FixedSOMLineCollection.cs
- MaxValueConverter.cs
- WindowsContainer.cs
- SystemNetHelpers.cs
- BooleanStorage.cs
- IntellisenseTextBox.designer.cs
- PathStreamGeometryContext.cs
- SizeConverter.cs