Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Map / Update / Internal / ExtractorMetadata.cs / 2 / 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
{
///
/// 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(StructuralType type, UpdateTranslator translator)
{
m_type = EntityUtil.CheckArgumentNull(type, "type");
m_translator = EntityUtil.CheckArgumentNull(translator, "translator");
Set keyMembers;
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(type.Members).MakeReadOnly();
break;
case BuiltInTypeKind.EntityType:
keyMembers = new Set(((EntityType)type).KeyMembers).MakeReadOnly();
break;
default:
keyMembers = Set.Empty;
break;
}
m_memberMap = new Dictionary();
IBaseList members = TypeHelpers.GetAllStructuralMembers(type);
// 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;
if (keyMembers.Contains(member))
{
flags |= PropagatorFlags.Key;
}
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(member);
// figure out whether member nullability is used as a condition in mapping
bool isNullConditionMember = m_translator.ViewLoader.IsNullConditionMember(member);
// add information about this member
m_memberMap.Add(member.Name, new MemberInformation(ordinal, flags, member, isServerGenerated, isNullConditionMember));
}
}
private readonly Dictionary m_memberMap;
private readonly StructuralType m_type;
private readonly UpdateTranslator m_translator;
///
/// Given a state entry, returns a bit array indicating which members
/// have been modified by ordinal.
/// Requires: state entry matches the type metadata described by this instance.
///
///
/// state manager entry for which to identify modified properties
/// Modified properties bit array. If null is returned, this indicates all properties
/// are modified.
internal BitArray GetModifiedPropertiesBitArray(IEnumerable modifiedProperties, IEntityStateEntry stateEntry)
{
int memberCount = TypeHelpers.GetAllStructuralMembers(m_type).Count;
if (null == modifiedProperties)
{
// all properties are modified when the state entry is not being modified (it's being inserted
// or deleted) or the modified list is null
return null;
}
BitArray result = new BitArray(memberCount, false);
foreach (string modifiedProperty in modifiedProperties)
{
MemberInformation memberInformation;
if (!m_memberMap.TryGetValue(modifiedProperty, out memberInformation))
{
throw EntityUtil.Update(System.Data.Entity.Strings.Update_MissingModifiedProperty(modifiedProperty, m_type.Name), null, stateEntry);
}
result[memberInformation.Ordinal] = true;
}
return result;
}
///
/// Requires: record must have correct type for this metadata instance.
/// Populates a new 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.
///
/// state manager entry containing value (used for error reporting)
/// Record containing value (used to find the actual value)
/// Entity key for the state entry. Must be set for entity records.
/// Member for which to retrieve a value.
/// Bit array indicating which members of the type are
/// modified (must be ordinally aligned with the type). Null indicates all members are modified.
/// Propagator result describing this member value.
internal PropagatorResult RetrieveMember(IEntityStateEntry stateEntry, IExtendedDataRecord record,
EntityKey key, EdmMember member, BitArray modifiedProperties)
{
MemberInformation memberInformation = m_memberMap[member.Name];
// get identifier value
Int64 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");
IList keyMembers = ((EntitySet)stateEntry.EntitySet).ElementType.KeyMembers;
int keyOrdinal = keyMembers.IndexOf(member);
identifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(key, keyOrdinal, keyMembers.Count);
}
else
{
identifier = PropagatorResult.NullIdentifier;
}
// determine if the member is modified
bool isModified = null == modifiedProperties || // null indicates all properties are modified
modifiedProperties[memberInformation.Ordinal];
// determine member value
int recordOrdinal = record.GetOrdinal(member.Name);
if (memberInformation.CheckIsNotNull && record.IsDBNull(recordOrdinal))
{
throw EntityUtil.Update(Strings.Update_NullValue(member.Name), null, stateEntry);
}
object value = record.GetValue(recordOrdinal);
// 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
IEnumerable nestedModifiedPropertyNames = isModified ?
null : // indicates all properties are modified
Enumerable.Empty(); // indicates no properties are modified
UpdateTranslator translator = m_translator;
return ExtractResultFromRecord(stateEntry, isModified, nestedRecord, nestedModifiedPropertyNames, translator);
}
// simple value (column/property value)
return CreateSimpleResult(stateEntry, record, memberInformation, identifier, isModified, recordOrdinal, 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(keyRowType);
int keyMemberCount = keyRowType.Members.Count;
PropagatorResult[] keyValues = new PropagatorResult[keyMemberCount];
for (int ordinal = 0; ordinal < keyRowType.Members.Count; ordinal++)
{
EdmMember keyMember = keyRowType.Members[ordinal];
// retrieve information about this key value
MemberInformation keyMemberInformation = keyMetadata.m_memberMap[keyMember.Name];
long keyIdentifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(entityKey, ordinal, keyRowType.Members.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,
Int64 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 && 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 && 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
/// Names of modified properties
/// Translator for session context; registers new metadata for the record type if none
/// exists
/// Result corresponding to the given record
internal static PropagatorResult ExtractResultFromRecord(IEntityStateEntry stateEntry, bool isModified, IExtendedDataRecord record,
IEnumerable modifiedPropertyNames, UpdateTranslator translator)
{
StructuralType structuralType = (StructuralType)record.DataRecordInfo.RecordType.EdmType;
ExtractorMetadata metadata = translator.GetExtractorMetadata(structuralType);
EntityKey key = stateEntry.EntityKey;
// get bit array describing modified properties
BitArray modifiedProperties = metadata.GetModifiedPropertiesBitArray(modifiedPropertyNames,
stateEntry);
// construct values for members of complex type
IBaseList members = TypeHelpers.GetAllStructuralMembers(structuralType);
PropagatorResult[] nestedValues = new PropagatorResult[members.Count];
for (int ordinal = 0; ordinal < nestedValues.Length; ordinal++)
{
EdmMember nestedMember = members[ordinal];
nestedValues[ordinal] = metadata.RetrieveMember(stateEntry, record, key,
nestedMember, modifiedProperties);
}
return PropagatorResult.CreateStructuralValue(nestedValues, structuralType, isModified);
}
private class MemberInformation
{
///
/// Gets ordinal of the member.
///
internal readonly int Ordinal;
///
/// 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 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, PropagatorFlags flags, EdmMember member, bool isServerGenerated, bool isNullConditionMember)
{
this.Ordinal = ordinal;
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
{
///
/// 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(StructuralType type, UpdateTranslator translator)
{
m_type = EntityUtil.CheckArgumentNull(type, "type");
m_translator = EntityUtil.CheckArgumentNull(translator, "translator");
Set keyMembers;
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(type.Members).MakeReadOnly();
break;
case BuiltInTypeKind.EntityType:
keyMembers = new Set(((EntityType)type).KeyMembers).MakeReadOnly();
break;
default:
keyMembers = Set.Empty;
break;
}
m_memberMap = new Dictionary();
IBaseList members = TypeHelpers.GetAllStructuralMembers(type);
// 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;
if (keyMembers.Contains(member))
{
flags |= PropagatorFlags.Key;
}
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(member);
// figure out whether member nullability is used as a condition in mapping
bool isNullConditionMember = m_translator.ViewLoader.IsNullConditionMember(member);
// add information about this member
m_memberMap.Add(member.Name, new MemberInformation(ordinal, flags, member, isServerGenerated, isNullConditionMember));
}
}
private readonly Dictionary m_memberMap;
private readonly StructuralType m_type;
private readonly UpdateTranslator m_translator;
///
/// Given a state entry, returns a bit array indicating which members
/// have been modified by ordinal.
/// Requires: state entry matches the type metadata described by this instance.
///
///
/// state manager entry for which to identify modified properties
/// Modified properties bit array. If null is returned, this indicates all properties
/// are modified.
internal BitArray GetModifiedPropertiesBitArray(IEnumerable modifiedProperties, IEntityStateEntry stateEntry)
{
int memberCount = TypeHelpers.GetAllStructuralMembers(m_type).Count;
if (null == modifiedProperties)
{
// all properties are modified when the state entry is not being modified (it's being inserted
// or deleted) or the modified list is null
return null;
}
BitArray result = new BitArray(memberCount, false);
foreach (string modifiedProperty in modifiedProperties)
{
MemberInformation memberInformation;
if (!m_memberMap.TryGetValue(modifiedProperty, out memberInformation))
{
throw EntityUtil.Update(System.Data.Entity.Strings.Update_MissingModifiedProperty(modifiedProperty, m_type.Name), null, stateEntry);
}
result[memberInformation.Ordinal] = true;
}
return result;
}
///
/// Requires: record must have correct type for this metadata instance.
/// Populates a new 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.
///
/// state manager entry containing value (used for error reporting)
/// Record containing value (used to find the actual value)
/// Entity key for the state entry. Must be set for entity records.
/// Member for which to retrieve a value.
/// Bit array indicating which members of the type are
/// modified (must be ordinally aligned with the type). Null indicates all members are modified.
/// Propagator result describing this member value.
internal PropagatorResult RetrieveMember(IEntityStateEntry stateEntry, IExtendedDataRecord record,
EntityKey key, EdmMember member, BitArray modifiedProperties)
{
MemberInformation memberInformation = m_memberMap[member.Name];
// get identifier value
Int64 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");
IList keyMembers = ((EntitySet)stateEntry.EntitySet).ElementType.KeyMembers;
int keyOrdinal = keyMembers.IndexOf(member);
identifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(key, keyOrdinal, keyMembers.Count);
}
else
{
identifier = PropagatorResult.NullIdentifier;
}
// determine if the member is modified
bool isModified = null == modifiedProperties || // null indicates all properties are modified
modifiedProperties[memberInformation.Ordinal];
// determine member value
int recordOrdinal = record.GetOrdinal(member.Name);
if (memberInformation.CheckIsNotNull && record.IsDBNull(recordOrdinal))
{
throw EntityUtil.Update(Strings.Update_NullValue(member.Name), null, stateEntry);
}
object value = record.GetValue(recordOrdinal);
// 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
IEnumerable nestedModifiedPropertyNames = isModified ?
null : // indicates all properties are modified
Enumerable.Empty(); // indicates no properties are modified
UpdateTranslator translator = m_translator;
return ExtractResultFromRecord(stateEntry, isModified, nestedRecord, nestedModifiedPropertyNames, translator);
}
// simple value (column/property value)
return CreateSimpleResult(stateEntry, record, memberInformation, identifier, isModified, recordOrdinal, 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(keyRowType);
int keyMemberCount = keyRowType.Members.Count;
PropagatorResult[] keyValues = new PropagatorResult[keyMemberCount];
for (int ordinal = 0; ordinal < keyRowType.Members.Count; ordinal++)
{
EdmMember keyMember = keyRowType.Members[ordinal];
// retrieve information about this key value
MemberInformation keyMemberInformation = keyMetadata.m_memberMap[keyMember.Name];
long keyIdentifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(entityKey, ordinal, keyRowType.Members.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,
Int64 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 && 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 && 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
/// Names of modified properties
/// Translator for session context; registers new metadata for the record type if none
/// exists
/// Result corresponding to the given record
internal static PropagatorResult ExtractResultFromRecord(IEntityStateEntry stateEntry, bool isModified, IExtendedDataRecord record,
IEnumerable modifiedPropertyNames, UpdateTranslator translator)
{
StructuralType structuralType = (StructuralType)record.DataRecordInfo.RecordType.EdmType;
ExtractorMetadata metadata = translator.GetExtractorMetadata(structuralType);
EntityKey key = stateEntry.EntityKey;
// get bit array describing modified properties
BitArray modifiedProperties = metadata.GetModifiedPropertiesBitArray(modifiedPropertyNames,
stateEntry);
// construct values for members of complex type
IBaseList members = TypeHelpers.GetAllStructuralMembers(structuralType);
PropagatorResult[] nestedValues = new PropagatorResult[members.Count];
for (int ordinal = 0; ordinal < nestedValues.Length; ordinal++)
{
EdmMember nestedMember = members[ordinal];
nestedValues[ordinal] = metadata.RetrieveMember(stateEntry, record, key,
nestedMember, modifiedProperties);
}
return PropagatorResult.CreateStructuralValue(nestedValues, structuralType, isModified);
}
private class MemberInformation
{
///
/// Gets ordinal of the member.
///
internal readonly int Ordinal;
///
/// 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 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, PropagatorFlags flags, EdmMember member, bool isServerGenerated, bool isNullConditionMember)
{
this.Ordinal = ordinal;
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
- DataSourceCache.cs
- WindowManager.cs
- ApplicationGesture.cs
- TextDecorationCollectionConverter.cs
- QueryAsyncResult.cs
- ConnectionConsumerAttribute.cs
- SizeValueSerializer.cs
- Vector3D.cs
- xmlsaver.cs
- TransformerConfigurationWizardBase.cs
- ScalarOps.cs
- WeakReference.cs
- WorkflowOwnershipException.cs
- TypeAccessException.cs
- EndOfStreamException.cs
- ListItem.cs
- GradientBrush.cs
- ExpressionVisitor.cs
- OpenCollectionAsyncResult.cs
- BitFlagsGenerator.cs
- SqlDataReader.cs
- CreateUserWizardStep.cs
- XmlSchemaInfo.cs
- Int64AnimationUsingKeyFrames.cs
- SelectionPattern.cs
- DataGridViewCellFormattingEventArgs.cs
- SectionXmlInfo.cs
- ColorAnimationUsingKeyFrames.cs
- SessionState.cs
- ListBoxItemWrapperAutomationPeer.cs
- WorkflowLayouts.cs
- SafeBitVector32.cs
- HyperLinkDataBindingHandler.cs
- XmlSchemaProviderAttribute.cs
- GenericTransactionFlowAttribute.cs
- XmlSignatureManifest.cs
- CodeParameterDeclarationExpression.cs
- DrawingState.cs
- ExpressionList.cs
- RelationshipEntry.cs
- ResXBuildProvider.cs
- ExecutionScope.cs
- Tablet.cs
- SqlTransaction.cs
- PagerSettings.cs
- WebPartDisplayModeEventArgs.cs
- COM2TypeInfoProcessor.cs
- LicenseProviderAttribute.cs
- JsonStringDataContract.cs
- OuterGlowBitmapEffect.cs
- UnsafeCollabNativeMethods.cs
- HtmlInputCheckBox.cs
- ClientApiGenerator.cs
- TextServicesLoader.cs
- SoapAttributes.cs
- BlobPersonalizationState.cs
- WinEventHandler.cs
- PathSegment.cs
- XmlUrlResolver.cs
- TypedLocationWrapper.cs
- ContentPlaceHolder.cs
- NotifyInputEventArgs.cs
- InternalReceiveMessage.cs
- SafeHGlobalHandleCritical.cs
- GPRECT.cs
- InputReferenceExpression.cs
- BehaviorService.cs
- NonBatchDirectoryCompiler.cs
- HTTP_SERVICE_CONFIG_URLACL_KEY.cs
- ServiceNameCollection.cs
- VisualStyleRenderer.cs
- MiniCustomAttributeInfo.cs
- HttpInputStream.cs
- XPathPatternParser.cs
- TaiwanLunisolarCalendar.cs
- EncoderReplacementFallback.cs
- XPathScanner.cs
- TreeIterator.cs
- RegexNode.cs
- LogManagementAsyncResult.cs
- MemberJoinTreeNode.cs
- TreeNodeConverter.cs
- CubicEase.cs
- HierarchicalDataSourceControl.cs
- DirtyTextRange.cs
- DataSourceViewSchemaConverter.cs
- DataObjectEventArgs.cs
- DataExchangeServiceBinder.cs
- FormViewUpdateEventArgs.cs
- ModelTypeConverter.cs
- OdbcParameter.cs
- Normalization.cs
- DataErrorValidationRule.cs
- TripleDESCryptoServiceProvider.cs
- ProfileBuildProvider.cs
- ParentQuery.cs
- SiteMapNodeItemEventArgs.cs
- ApplicationTrust.cs
- BaseDataBoundControl.cs
- DBCSCodePageEncoding.cs