Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DLinq / Dlinq / ChangeConflicts.cs / 2 / ChangeConflicts.cs
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; using System.Reflection; using System.Linq; using System.Diagnostics; namespace System.Data.Linq { using System.Data.Linq.Mapping; using System.Data.Linq.Provider; using System.Diagnostics.CodeAnalysis; public sealed class ChangeConflictCollection : ICollection, ICollection, IEnumerable , IEnumerable { private List conflicts; internal ChangeConflictCollection() { this.conflicts = new List (); } /// /// The number of conflicts in the collection /// public int Count { get { return this.conflicts.Count; } } public ObjectChangeConflict this[int index] { get { return this.conflicts[index]; } } bool ICollection.IsReadOnly { get { return true; } } void ICollection .Add(ObjectChangeConflict item) { throw Error.CannotAddChangeConflicts(); } /// /// Removes the specified conflict from the collection. /// /// The conflict to remove ///public bool Remove(ObjectChangeConflict item) { return this.conflicts.Remove(item); } /// /// Removes all conflicts from the collection /// public void Clear() { this.conflicts.Clear(); } ////// Returns true if the specified conflict is a member of the collection. /// /// ///public bool Contains(ObjectChangeConflict item) { return this.conflicts.Contains(item); } public void CopyTo(ObjectChangeConflict[] array, int arrayIndex) { this.conflicts.CopyTo(array, arrayIndex); } /// /// Returns the enumerator for the collection. /// ///public IEnumerator GetEnumerator() { return this.conflicts.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return this.conflicts.GetEnumerator(); } bool ICollection.IsSynchronized { get { return false; } } object ICollection.SyncRoot { get { return null; } } void ICollection.CopyTo(Array array, int index) { ((ICollection)this.conflicts).CopyTo(array, index); } /// /// Resolves all conflicts in the collection using the specified strategy. /// /// The strategy to use to resolve the conflicts. public void ResolveAll(RefreshMode mode) { this.ResolveAll(mode, true); } ////// Resolves all conflicts in the collection using the specified strategy. /// /// The strategy to use to resolve the conflicts. /// If true conflicts resulting from the modified /// object no longer existing in the database will be automatically resolved. public void ResolveAll(RefreshMode mode, bool autoResolveDeletes) { foreach (ObjectChangeConflict c in this.conflicts) { if (!c.IsResolved) { c.Resolve(mode, autoResolveDeletes); } } } internal void Fill(ListconflictList) { this.conflicts = conflictList; } } internal sealed class ChangeConflictSession { private DataContext context; private DataContext refreshContext; internal ChangeConflictSession(DataContext context) { this.context = context; } internal DataContext Context { get { return this.context; } } internal DataContext RefreshContext { get { if (this.refreshContext == null) { this.refreshContext = this.context.CreateRefreshContext(); } return this.refreshContext; } } } /// /// Represents an update with one or more optimistic concurrency conflicts. /// public sealed class ObjectChangeConflict { private ChangeConflictSession session; private TrackedObject trackedObject; private bool isResolved; private ReadOnlyCollectionmemberConflicts; private object database; private object original; private bool? isDeleted; /// /// Constructor. /// /// The session in which the conflicts occurred. /// The tracked item in conflict. internal ObjectChangeConflict(ChangeConflictSession session, TrackedObject trackedObject) { this.session = session; this.trackedObject = trackedObject; this.original = trackedObject.CreateDataCopy(trackedObject.Original); } ////// Constructor. /// /// The session in which the conflicts occurred. /// The tracked item in conflict. /// True if the item in conflict no longer exists in the database. internal ObjectChangeConflict(ChangeConflictSession session, TrackedObject trackedObject, bool isDeleted) : this(session, trackedObject) { this.isDeleted = isDeleted; } internal ChangeConflictSession Session { get { return this.session; } } internal TrackedObject TrackedObject { get { return this.trackedObject; } } ////// The object in conflict. /// public object Object { get { return this.trackedObject.Current; } } ////// An instance containing the baseline original values used to perform the concurrency check. /// internal object Original { get { return this.original; } } ////// True if the conflicts for this object have already been resovled. /// public bool IsResolved { get { return this.isResolved; } } ////// True if the object in conflict has been deleted from the database. /// public bool IsDeleted { get { if (this.isDeleted.HasValue) { return this.isDeleted.Value; } return (this.Database == null); } } ////// An instance containing the most recent values from the database /// internal object Database { get { if (this.database == null) { // use the 'refresh' context to retrieve the current database state DataContext ctxt = this.session.RefreshContext; object[] keyValues = CommonDataServices.GetKeyValues(this.trackedObject.Type, this.original); this.database = ctxt.Services.GetObjectByKey(this.trackedObject.Type, keyValues); } return this.database; } } ////// Resolve member conflicts keeping current values and resetting the baseline 'Original' values /// to match the more recent 'Database' values. /// public void Resolve() { this.Resolve(RefreshMode.KeepCurrentValues, true); } ////// Resolve member conflicts using the mode specified and resetting the baseline 'Original' values /// to match the more recent 'Database' values. /// /// The mode that determines how the current values are /// changed in order to resolve the conflict public void Resolve(RefreshMode refreshMode) { this.Resolve(refreshMode, false); } ////// Resolve member conflicts using the mode specified and resetting the baseline 'Original' values /// to match the more recent 'Database' values. /// /// The mode that determines how the current values are /// changed in order to resolve the conflict /// If true conflicts resulting from the modified /// object no longer existing in the database will be automatically resolved. public void Resolve(RefreshMode refreshMode, bool autoResolveDeletes) { if (autoResolveDeletes && this.IsDeleted) { this.ResolveDelete(); } else { // We make these calls explicity rather than simply calling // DataContext.Refresh (which does virtually the same thing) // since we want to cache the database value read. if (this.Database == null) { throw Error.RefreshOfDeletedObject(); } trackedObject.Refresh(refreshMode, this.Database); this.isResolved = true; } } ////// Resolve a conflict where we have updated an entity that no longer exists /// in the database. /// private void ResolveDelete() { Debug.Assert(this.IsDeleted); // If the user is attempting to update an entity that no longer exists // in the database, we first need to [....] the delete into the local cache. if (!trackedObject.IsDeleted) { trackedObject.ConvertToDeleted(); } // Now that our cache is in [....], we accept the changes this.trackedObject.AcceptChanges(); this.isResolved = true; } ////// Returns a collection of all member conflicts that caused the update to fail. /// public ReadOnlyCollectionMemberConflicts { get { if (this.memberConflicts == null) { var list = new List (); if (this.Database != null) { // determine which members are in conflict foreach (MetaDataMember metaMember in trackedObject.Type.PersistentDataMembers) { if (!metaMember.IsAssociation && this.HasMemberConflict(metaMember)) { list.Add(new MemberChangeConflict(this, metaMember)); } } } this.memberConflicts = list.AsReadOnly(); } return this.memberConflicts; } } private bool HasMemberConflict(MetaDataMember member) { object oValue = member.StorageAccessor.GetBoxedValue(this.original); if (!member.DeclaringType.Type.IsAssignableFrom(this.database.GetType())) { return false; } object dValue = member.StorageAccessor.GetBoxedValue(this.database); return !this.AreEqual(member, oValue, dValue); } private bool AreEqual(MetaDataMember member, object v1, object v2) { if (v1 == null && v2 == null) return true; if (v1 == null || v2 == null) return false; if (member.Type == typeof(char[])) { return this.AreEqual((char[])v1, (char[])v2); } else if (member.Type == typeof(byte[])) { return this.AreEqual((byte[])v1, (byte[])v2); } else { return object.Equals(v1, v2); } } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private bool AreEqual(char[] a1, char[] a2) { if (a1.Length != a2.Length) return false; for (int i = 0, n = a1.Length; i < n; i++) { if (a1[i] != a2[i]) return false; } return true; } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private bool AreEqual(byte[] a1, byte[] a2) { if (a1.Length != a2.Length) return false; for (int i = 0, n = a1.Length; i < n; i++) { if (a1[i] != a2[i]) return false; } return true; } internal void OnMemberResolved() { if (!this.IsResolved) { int nResolved = this.memberConflicts.AsEnumerable().Count(m => m.IsResolved); if (nResolved == this.memberConflicts.Count) { this.Resolve(RefreshMode.KeepCurrentValues, false); } } } } /// /// Represents a single optimistic concurrency member conflict. /// public sealed class MemberChangeConflict { private ObjectChangeConflict conflict; private MetaDataMember metaMember; private object originalValue; private object databaseValue; private object currentValue; bool isResolved; internal MemberChangeConflict(ObjectChangeConflict conflict, MetaDataMember metaMember) { this.conflict = conflict; this.metaMember = metaMember; this.originalValue = metaMember.StorageAccessor.GetBoxedValue(conflict.Original); this.databaseValue = metaMember.StorageAccessor.GetBoxedValue(conflict.Database); this.currentValue = metaMember.StorageAccessor.GetBoxedValue(conflict.TrackedObject.Current); } ////// The previous client value. /// public object OriginalValue { get { return this.originalValue; } } ////// The current database value. /// public object DatabaseValue { get { return this.databaseValue; } } ////// The current client value. /// public object CurrentValue { get { return this.currentValue; } } ////// MemberInfo for the member in conflict. /// public MemberInfo Member { get { return this.metaMember.Member; } } ////// Updates the current value to the specified value. /// public void Resolve(object value) { this.conflict.TrackedObject.RefreshMember(this.metaMember, RefreshMode.OverwriteCurrentValues, value); this.isResolved = true; this.conflict.OnMemberResolved(); } ////// Updates the current value using the specified strategy. /// public void Resolve(RefreshMode refreshMode) { this.conflict.TrackedObject.RefreshMember(this.metaMember, refreshMode, this.databaseValue); this.isResolved = true; this.conflict.OnMemberResolved(); } ////// True if the value was modified by the client. /// public bool IsModified { get { return this.conflict.TrackedObject.HasChangedValue(this.metaMember); } } ////// True if the member conflict has been resolved. /// public bool IsResolved { get { return this.isResolved; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text; using System.Reflection; using System.Linq; using System.Diagnostics; namespace System.Data.Linq { using System.Data.Linq.Mapping; using System.Data.Linq.Provider; using System.Diagnostics.CodeAnalysis; public sealed class ChangeConflictCollection : ICollection, ICollection, IEnumerable , IEnumerable { private List conflicts; internal ChangeConflictCollection() { this.conflicts = new List (); } /// /// The number of conflicts in the collection /// public int Count { get { return this.conflicts.Count; } } public ObjectChangeConflict this[int index] { get { return this.conflicts[index]; } } bool ICollection.IsReadOnly { get { return true; } } void ICollection .Add(ObjectChangeConflict item) { throw Error.CannotAddChangeConflicts(); } /// /// Removes the specified conflict from the collection. /// /// The conflict to remove ///public bool Remove(ObjectChangeConflict item) { return this.conflicts.Remove(item); } /// /// Removes all conflicts from the collection /// public void Clear() { this.conflicts.Clear(); } ////// Returns true if the specified conflict is a member of the collection. /// /// ///public bool Contains(ObjectChangeConflict item) { return this.conflicts.Contains(item); } public void CopyTo(ObjectChangeConflict[] array, int arrayIndex) { this.conflicts.CopyTo(array, arrayIndex); } /// /// Returns the enumerator for the collection. /// ///public IEnumerator GetEnumerator() { return this.conflicts.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return this.conflicts.GetEnumerator(); } bool ICollection.IsSynchronized { get { return false; } } object ICollection.SyncRoot { get { return null; } } void ICollection.CopyTo(Array array, int index) { ((ICollection)this.conflicts).CopyTo(array, index); } /// /// Resolves all conflicts in the collection using the specified strategy. /// /// The strategy to use to resolve the conflicts. public void ResolveAll(RefreshMode mode) { this.ResolveAll(mode, true); } ////// Resolves all conflicts in the collection using the specified strategy. /// /// The strategy to use to resolve the conflicts. /// If true conflicts resulting from the modified /// object no longer existing in the database will be automatically resolved. public void ResolveAll(RefreshMode mode, bool autoResolveDeletes) { foreach (ObjectChangeConflict c in this.conflicts) { if (!c.IsResolved) { c.Resolve(mode, autoResolveDeletes); } } } internal void Fill(ListconflictList) { this.conflicts = conflictList; } } internal sealed class ChangeConflictSession { private DataContext context; private DataContext refreshContext; internal ChangeConflictSession(DataContext context) { this.context = context; } internal DataContext Context { get { return this.context; } } internal DataContext RefreshContext { get { if (this.refreshContext == null) { this.refreshContext = this.context.CreateRefreshContext(); } return this.refreshContext; } } } /// /// Represents an update with one or more optimistic concurrency conflicts. /// public sealed class ObjectChangeConflict { private ChangeConflictSession session; private TrackedObject trackedObject; private bool isResolved; private ReadOnlyCollectionmemberConflicts; private object database; private object original; private bool? isDeleted; /// /// Constructor. /// /// The session in which the conflicts occurred. /// The tracked item in conflict. internal ObjectChangeConflict(ChangeConflictSession session, TrackedObject trackedObject) { this.session = session; this.trackedObject = trackedObject; this.original = trackedObject.CreateDataCopy(trackedObject.Original); } ////// Constructor. /// /// The session in which the conflicts occurred. /// The tracked item in conflict. /// True if the item in conflict no longer exists in the database. internal ObjectChangeConflict(ChangeConflictSession session, TrackedObject trackedObject, bool isDeleted) : this(session, trackedObject) { this.isDeleted = isDeleted; } internal ChangeConflictSession Session { get { return this.session; } } internal TrackedObject TrackedObject { get { return this.trackedObject; } } ////// The object in conflict. /// public object Object { get { return this.trackedObject.Current; } } ////// An instance containing the baseline original values used to perform the concurrency check. /// internal object Original { get { return this.original; } } ////// True if the conflicts for this object have already been resovled. /// public bool IsResolved { get { return this.isResolved; } } ////// True if the object in conflict has been deleted from the database. /// public bool IsDeleted { get { if (this.isDeleted.HasValue) { return this.isDeleted.Value; } return (this.Database == null); } } ////// An instance containing the most recent values from the database /// internal object Database { get { if (this.database == null) { // use the 'refresh' context to retrieve the current database state DataContext ctxt = this.session.RefreshContext; object[] keyValues = CommonDataServices.GetKeyValues(this.trackedObject.Type, this.original); this.database = ctxt.Services.GetObjectByKey(this.trackedObject.Type, keyValues); } return this.database; } } ////// Resolve member conflicts keeping current values and resetting the baseline 'Original' values /// to match the more recent 'Database' values. /// public void Resolve() { this.Resolve(RefreshMode.KeepCurrentValues, true); } ////// Resolve member conflicts using the mode specified and resetting the baseline 'Original' values /// to match the more recent 'Database' values. /// /// The mode that determines how the current values are /// changed in order to resolve the conflict public void Resolve(RefreshMode refreshMode) { this.Resolve(refreshMode, false); } ////// Resolve member conflicts using the mode specified and resetting the baseline 'Original' values /// to match the more recent 'Database' values. /// /// The mode that determines how the current values are /// changed in order to resolve the conflict /// If true conflicts resulting from the modified /// object no longer existing in the database will be automatically resolved. public void Resolve(RefreshMode refreshMode, bool autoResolveDeletes) { if (autoResolveDeletes && this.IsDeleted) { this.ResolveDelete(); } else { // We make these calls explicity rather than simply calling // DataContext.Refresh (which does virtually the same thing) // since we want to cache the database value read. if (this.Database == null) { throw Error.RefreshOfDeletedObject(); } trackedObject.Refresh(refreshMode, this.Database); this.isResolved = true; } } ////// Resolve a conflict where we have updated an entity that no longer exists /// in the database. /// private void ResolveDelete() { Debug.Assert(this.IsDeleted); // If the user is attempting to update an entity that no longer exists // in the database, we first need to [....] the delete into the local cache. if (!trackedObject.IsDeleted) { trackedObject.ConvertToDeleted(); } // Now that our cache is in [....], we accept the changes this.trackedObject.AcceptChanges(); this.isResolved = true; } ////// Returns a collection of all member conflicts that caused the update to fail. /// public ReadOnlyCollectionMemberConflicts { get { if (this.memberConflicts == null) { var list = new List (); if (this.Database != null) { // determine which members are in conflict foreach (MetaDataMember metaMember in trackedObject.Type.PersistentDataMembers) { if (!metaMember.IsAssociation && this.HasMemberConflict(metaMember)) { list.Add(new MemberChangeConflict(this, metaMember)); } } } this.memberConflicts = list.AsReadOnly(); } return this.memberConflicts; } } private bool HasMemberConflict(MetaDataMember member) { object oValue = member.StorageAccessor.GetBoxedValue(this.original); if (!member.DeclaringType.Type.IsAssignableFrom(this.database.GetType())) { return false; } object dValue = member.StorageAccessor.GetBoxedValue(this.database); return !this.AreEqual(member, oValue, dValue); } private bool AreEqual(MetaDataMember member, object v1, object v2) { if (v1 == null && v2 == null) return true; if (v1 == null || v2 == null) return false; if (member.Type == typeof(char[])) { return this.AreEqual((char[])v1, (char[])v2); } else if (member.Type == typeof(byte[])) { return this.AreEqual((byte[])v1, (byte[])v2); } else { return object.Equals(v1, v2); } } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private bool AreEqual(char[] a1, char[] a2) { if (a1.Length != a2.Length) return false; for (int i = 0, n = a1.Length; i < n; i++) { if (a1[i] != a2[i]) return false; } return true; } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private bool AreEqual(byte[] a1, byte[] a2) { if (a1.Length != a2.Length) return false; for (int i = 0, n = a1.Length; i < n; i++) { if (a1[i] != a2[i]) return false; } return true; } internal void OnMemberResolved() { if (!this.IsResolved) { int nResolved = this.memberConflicts.AsEnumerable().Count(m => m.IsResolved); if (nResolved == this.memberConflicts.Count) { this.Resolve(RefreshMode.KeepCurrentValues, false); } } } } /// /// Represents a single optimistic concurrency member conflict. /// public sealed class MemberChangeConflict { private ObjectChangeConflict conflict; private MetaDataMember metaMember; private object originalValue; private object databaseValue; private object currentValue; bool isResolved; internal MemberChangeConflict(ObjectChangeConflict conflict, MetaDataMember metaMember) { this.conflict = conflict; this.metaMember = metaMember; this.originalValue = metaMember.StorageAccessor.GetBoxedValue(conflict.Original); this.databaseValue = metaMember.StorageAccessor.GetBoxedValue(conflict.Database); this.currentValue = metaMember.StorageAccessor.GetBoxedValue(conflict.TrackedObject.Current); } ////// The previous client value. /// public object OriginalValue { get { return this.originalValue; } } ////// The current database value. /// public object DatabaseValue { get { return this.databaseValue; } } ////// The current client value. /// public object CurrentValue { get { return this.currentValue; } } ////// MemberInfo for the member in conflict. /// public MemberInfo Member { get { return this.metaMember.Member; } } ////// Updates the current value to the specified value. /// public void Resolve(object value) { this.conflict.TrackedObject.RefreshMember(this.metaMember, RefreshMode.OverwriteCurrentValues, value); this.isResolved = true; this.conflict.OnMemberResolved(); } ////// Updates the current value using the specified strategy. /// public void Resolve(RefreshMode refreshMode) { this.conflict.TrackedObject.RefreshMember(this.metaMember, refreshMode, this.databaseValue); this.isResolved = true; this.conflict.OnMemberResolved(); } ////// True if the value was modified by the client. /// public bool IsModified { get { return this.conflict.TrackedObject.HasChangedValue(this.metaMember); } } ////// True if the member conflict has been resolved. /// public bool IsResolved { get { return this.isResolved; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataContractJsonSerializer.cs
- XmlName.cs
- MailMessageEventArgs.cs
- SqlDataSourceCache.cs
- ExclusiveNamedPipeTransportManager.cs
- PassportPrincipal.cs
- RotateTransform3D.cs
- CompositeCollection.cs
- SqlProvider.cs
- CatalogZone.cs
- GenerateTemporaryAssemblyTask.cs
- CodePageUtils.cs
- CoTaskMemSafeHandle.cs
- SerializationFieldInfo.cs
- WebPartZoneBase.cs
- EdmFunction.cs
- ScrollItemProviderWrapper.cs
- XPathDocumentIterator.cs
- TemplateLookupAction.cs
- XDeferredAxisSource.cs
- RubberbandSelector.cs
- Monitor.cs
- DecoderFallback.cs
- CodeBlockBuilder.cs
- ImageField.cs
- UnsafeNativeMethods.cs
- ReadOnlyCollectionBuilder.cs
- DesignerAutoFormat.cs
- OdbcCommandBuilder.cs
- WorkflowMarkupSerializationException.cs
- WebPartMenu.cs
- OleServicesContext.cs
- X509WindowsSecurityToken.cs
- SqlAggregateChecker.cs
- ConditionalWeakTable.cs
- ConnectivityStatus.cs
- ManagementObjectSearcher.cs
- SocketPermission.cs
- ScriptServiceAttribute.cs
- ClientApiGenerator.cs
- StandardToolWindows.cs
- prefixendpointaddressmessagefiltertable.cs
- WpfKnownMemberInvoker.cs
- FixedSOMGroup.cs
- XPathSelfQuery.cs
- PassportIdentity.cs
- DefaultConfirmation.cs
- PrintPreviewControl.cs
- InheritanceAttribute.cs
- ScrollBar.cs
- TextEditorSelection.cs
- SimpleBitVector32.cs
- HttpProfileGroupBase.cs
- SQLMoney.cs
- QuaternionIndependentAnimationStorage.cs
- ResourceExpression.cs
- ModelUIElement3D.cs
- PhoneCall.cs
- SqlDataSourceCommandEventArgs.cs
- webproxy.cs
- DropShadowBitmapEffect.cs
- XpsSerializationManagerAsync.cs
- MobileErrorInfo.cs
- ConcurrentQueue.cs
- WebPartDisplayModeEventArgs.cs
- VirtualizingStackPanel.cs
- ListControl.cs
- PasswordRecovery.cs
- CustomAssemblyResolver.cs
- ServiceBehaviorElement.cs
- _ListenerResponseStream.cs
- XamlStyleSerializer.cs
- MenuAdapter.cs
- NamespaceTable.cs
- FontStyle.cs
- AutomationPeer.cs
- LoginUtil.cs
- DetailsViewUpdatedEventArgs.cs
- PositiveTimeSpanValidatorAttribute.cs
- WindowsAltTab.cs
- TemplateBindingExpression.cs
- Geometry.cs
- ScriptingRoleServiceSection.cs
- CustomAttributeSerializer.cs
- CompiledXpathExpr.cs
- SafeNativeMethods.cs
- SqlResolver.cs
- xmlglyphRunInfo.cs
- UnsafeNativeMethods.cs
- RowsCopiedEventArgs.cs
- CorrelationResolver.cs
- XmlDictionaryReaderQuotasElement.cs
- SemanticBasicElement.cs
- AuthenticationException.cs
- HideDisabledControlAdapter.cs
- BitVector32.cs
- GridViewItemAutomationPeer.cs
- ControlUtil.cs
- TextEffectResolver.cs
- Char.cs