EntityWrapper.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Objects / Internal / EntityWrapper.cs / 1305376 / EntityWrapper.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 
using System.Collections;
using System.Data.Objects.DataClasses; 
using System.Diagnostics;
using System.Reflection;
using System.Data.Metadata.Edm;
 
namespace System.Data.Objects.Internal
{ 
    ///  
    /// An extension of the EntityWrapper class for entities that are known not to implement
    /// IEntityWithRelationships.  Using this class causes the RelationshipManager to be created 
    /// independently.
    /// 
    /// The type of entity wrapped
    internal sealed class EntityWrapperWithoutRelationships : EntityWrapper 
    {
        ///  
        /// Constructs a wrapper as part of the materialization process.  This constructor is only used 
        /// during materialization where it is known that the entity being wrapped is newly constructed.
        /// This means that some checks are not performed that might be needed when thw wrapper is 
        /// created at other times, and information such as the identity type is passed in because
        /// it is readily available in the materializer.
        /// 
        /// The entity to wrap 
        /// The entity's key
        /// The entity set, or null if none is known 
        /// The context to which the entity should be attached 
        /// NoTracking for non-tracked entities, AppendOnly otherwise
        /// The type of the entity ignoring any possible proxy type 
        /// A delegate to create the property accesor strategy object
        /// A delegate to create the change tracking strategy object
        /// A delegate to create the entity key strategy object
        internal EntityWrapperWithoutRelationships(TEntity entity, EntityKey key, EntitySet entitySet, ObjectContext context, MergeOption mergeOption, Type identityType, 
                                                   Func propertyStrategy, Func changeTrackingStrategy, Func keyStrategy)
            : base(entity, RelationshipManager.Create(), key, entitySet, context, mergeOption, identityType, 
                   propertyStrategy, changeTrackingStrategy, keyStrategy) 
        {
        } 

        /// 
        /// Constructs a wrapper for the given entity.
        /// Note: use EntityWrapperFactory instead of calling this constructor directly. 
        /// 
        /// The entity to wrap 
        /// A delegate to create the property accesor strategy object 
        /// A delegate to create the change tracking strategy object
        /// A delegate to create the entity key strategy object 
        internal EntityWrapperWithoutRelationships(TEntity entity, Func propertyStrategy, Func changeTrackingStrategy, Func keyStrategy)
            : base(entity, RelationshipManager.Create(), propertyStrategy, changeTrackingStrategy, keyStrategy)
        {
        } 

        public override bool OwnsRelationshipManager 
        { 
            get { return false; }
        } 

        public override void TakeSnapshotOfRelationships(EntityEntry entry)
        {
            entry.TakeSnapshotOfRelationships(); 
        }
 
        // See IEntityWrapper documentation 
        public override bool RequiresRelationshipChangeTracking
        { 
            get { return true; }
        }

        // See IEntityWrapper documentation 
        public override bool RequiresAnyChangeTracking
        { 
            get { return true; } 
        }
    } 

    /// 
    /// An extension of the EntityWrapper class for entities that implement IEntityWithRelationships.
    /// Using this class causes creation of the RelationshipManager to be defered to the entity object. 
    /// 
    /// The type of entity wrapped 
    internal sealed class EntityWrapperWithRelationships : EntityWrapper 
        where TEntity : IEntityWithRelationships
    { 
        /// 
        /// Constructs a wrapper as part of the materialization process.  This constructor is only used
        /// during materialization where it is known that the entity being wrapped is newly constructed.
        /// This means that some checks are not performed that might be needed when thw wrapper is 
        /// created at other times, and information such as the identity type is passed in because
        /// it is readily available in the materializer. 
        ///  
        /// The entity to wrap
        /// The entity's key 
        /// The entity set, or null if none is known
        /// The context to which the entity should be attached
        /// NoTracking for non-tracked entities, AppendOnly otherwise
        /// The type of the entity ignoring any possible proxy type 
        /// A delegate to create the property accesor strategy object
        /// A delegate to create the change tracking strategy object 
        /// A delegate to create the entity key strategy object 
        internal EntityWrapperWithRelationships(TEntity entity, EntityKey key, EntitySet entitySet, ObjectContext context, MergeOption mergeOption, Type identityType,
                                                Func propertyStrategy, Func changeTrackingStrategy, Func keyStrategy) 
            : base(entity, entity.RelationshipManager, key, entitySet, context, mergeOption, identityType,
                   propertyStrategy, changeTrackingStrategy, keyStrategy)
        {
        } 

        ///  
        /// Constructs a wrapper for the given entity. 
        /// Note: use EntityWrapperFactory instead of calling this constructor directly.
        ///  
        /// The entity to wrap
        /// A delegate to create the property accesor strategy object
        /// A delegate to create the change tracking strategy object
        /// A delegate to create the entity key strategy object 
        internal EntityWrapperWithRelationships(TEntity entity, Func propertyStrategy, Func changeTrackingStrategy, Func keyStrategy)
            : base(entity, entity.RelationshipManager, propertyStrategy, changeTrackingStrategy, keyStrategy) 
        { 
        }
 
        public override bool OwnsRelationshipManager
        {
            get { return true; }
        } 

        public override void TakeSnapshotOfRelationships(EntityEntry entry) 
        { 
        }
 
        // See IEntityWrapper documentation
        public override bool RequiresRelationshipChangeTracking
        {
            get { return false; } 
        }
    } 
 
    /// 
    /// Implementation of the IEntityWrapper interface that is used for non-null entities that do not implement 
    /// all of our standard interfaces: IEntityWithKey, IEntityWithRelationships, and IEntityWithChangeTracker, and
    /// are not proxies.
    /// Different strategies for dealing with these entities are defined by strategy objects that are set into the
    /// wrapper at constructionn time. 
    /// 
    internal abstract class EntityWrapper : BaseEntityWrapper 
    { 
        private readonly TEntity _entity;
        private IPropertyAccessorStrategy _propertyStrategy; 
        private IChangeTrackingStrategy _changeTrackingStrategy;
        private IEntityKeyStrategy _keyStrategy;
        private static bool? _requiresComplexChangeTracking = null;
 
        /// 
        /// Constructs a wrapper for the given entity. 
        /// Note: use EntityWrapperFactory instead of calling this constructor directly. 
        /// 
        /// The entity to wrap 
        /// The RelationshipManager associated with the entity
        /// A delegate to create the property accesor strategy object
        /// A delegate to create the change tracking strategy object
        /// A delegate to create the entity key strategy object 
        protected EntityWrapper(TEntity entity, RelationshipManager relationshipManager,
                               Func propertyStrategy, Func changeTrackingStrategy, Func keyStrategy) 
            : base(entity, relationshipManager) 
        {
            if (relationshipManager == null) 
            {
                throw EntityUtil.UnexpectedNullRelationshipManager();
            }
            _entity = entity; 
            _propertyStrategy = propertyStrategy(entity);
            _changeTrackingStrategy = changeTrackingStrategy(entity); 
            _keyStrategy = keyStrategy(entity); 
            Debug.Assert(_changeTrackingStrategy != null, "Change tracking strategy cannot be null.");
            Debug.Assert(_keyStrategy != null, "Key strategy cannot be null."); 
        }

        /// 
        /// Constructs a wrapper as part of the materialization process.  This constructor is only used 
        /// during materialization where it is known that the entity being wrapped is newly constructed.
        /// This means that some checks are not performed that might be needed when thw wrapper is 
        /// created at other times, and information such as the identity type is passed in because 
        /// it is readily available in the materializer.
        ///  
        /// The entity to wrap
        /// The RelationshipManager associated with the entity
        /// The entity's key
        /// The entity set, or null if none is known 
        /// The context to which the entity should be attached
        /// NoTracking for non-tracked entities, AppendOnly otherwise 
        /// The type of the entity ignoring any possible proxy type 
        /// A delegate to create the property accesor strategy object
        /// A delegate to create the change tracking strategy object 
        /// A delegate to create the entity key strategy object
        protected EntityWrapper(TEntity entity, RelationshipManager relationshipManager, EntityKey key, EntitySet set, ObjectContext context, MergeOption mergeOption, Type identityType,
                               Func propertyStrategy, Func changeTrackingStrategy, Func keyStrategy)
            : base(entity, relationshipManager, set, context, mergeOption, identityType) 
        {
            if (relationshipManager == null) 
            { 
                throw EntityUtil.UnexpectedNullRelationshipManager();
            } 
            _entity = entity;
            _propertyStrategy = propertyStrategy(entity);
            _changeTrackingStrategy = changeTrackingStrategy(entity);
            _keyStrategy = keyStrategy(entity); 
            Debug.Assert(_changeTrackingStrategy != null, "Change tracking strategy cannot be null.");
            Debug.Assert(_keyStrategy != null, "Key strategy cannot be null."); 
            _keyStrategy.SetEntityKey(key); 
        }
 
        // See IEntityWrapper documentation
        public override void SetChangeTracker(IEntityChangeTracker changeTracker)
        {
            _changeTrackingStrategy.SetChangeTracker(changeTracker); 
        }
 
        // See IEntityWrapper documentation 
        public override void TakeSnapshot(EntityEntry entry)
        { 
            _changeTrackingStrategy.TakeSnapshot(entry);
        }

        // See IEntityWrapper documentation 
        public override EntityKey EntityKey
        { 
            // If no strategy is set, then the key maintained by the wrapper is used, 
            // otherwise the request is passed to the strategy.
            get 
            {
                return _keyStrategy.GetEntityKey();
            }
            set 
            {
                _keyStrategy.SetEntityKey(value); 
            } 
        }
 
        public override EntityKey GetEntityKeyFromEntity()
        {
            return _keyStrategy.GetEntityKeyFromEntity();
        } 

        public override void CollectionAdd(RelatedEnd relatedEnd, object value) 
        { 
            if (_propertyStrategy != null)
            { 
                _propertyStrategy.CollectionAdd(relatedEnd, value);
            }
        }
 
        public override bool CollectionRemove(RelatedEnd relatedEnd, object value)
        { 
            return _propertyStrategy != null ? _propertyStrategy.CollectionRemove(relatedEnd, value) : false; 
        }
 
        // See IEntityWrapper documentation
        public override void EnsureCollectionNotNull(RelatedEnd relatedEnd)
        {
            if (_propertyStrategy != null) 
            {
                object collection = _propertyStrategy.GetNavigationPropertyValue(relatedEnd); 
                if (collection == null) 
                {
                    collection = _propertyStrategy.CollectionCreate(relatedEnd); 
                    _propertyStrategy.SetNavigationPropertyValue(relatedEnd, collection);
                }
            }
        } 

        // See IEntityWrapper documentation 
        public override object GetNavigationPropertyValue(RelatedEnd relatedEnd) 
        {
            return _propertyStrategy != null ? _propertyStrategy.GetNavigationPropertyValue(relatedEnd) : null; 
        }

        // See IEntityWrapper documentation
        public override void SetNavigationPropertyValue(RelatedEnd relatedEnd, object value) 
        {
            if (_propertyStrategy != null) 
            { 
                _propertyStrategy.SetNavigationPropertyValue(relatedEnd, value);
            } 
        }

        // See IEntityWrapper documentation
        public override void RemoveNavigationPropertyValue(RelatedEnd relatedEnd, object value) 
        {
            if (_propertyStrategy != null) 
            { 
                object currentValue = _propertyStrategy.GetNavigationPropertyValue(relatedEnd);
 
                if (Object.ReferenceEquals(currentValue, value))
                {
                    _propertyStrategy.SetNavigationPropertyValue(relatedEnd, null);
                } 
            }
        } 
 
        // See IEntityWrapper documentation
        public override object Entity 
        {
            get { return _entity; }
        }
 
        // See IEntityWrapper documentation
        public override TEntity TypedEntity 
        { 
            get { return _entity; }
        } 

        // See IEntityWrapper documentation
        public override void SetCurrentValue(EntityEntry entry, StateManagerMemberMetadata member, int ordinal, object target, object value)
        { 
            _changeTrackingStrategy.SetCurrentValue(entry, member, ordinal, target, value);
        } 
 
        // See IEntityWrapper documentation
        public override void UpdateCurrentValueRecord(object value, EntityEntry entry) 
        {
            _changeTrackingStrategy.UpdateCurrentValueRecord(value, entry);
        }
 
        // See IEntityWrapper documentation
        public override bool RequiresComplexChangeTracking 
        { 
            get
            { 
                if (!_requiresComplexChangeTracking.HasValue)
                {
                    _requiresComplexChangeTracking = !(_entity is IEntityWithChangeTracker) || IdentityType != _entity.GetType();
                } 

                return _requiresComplexChangeTracking.Value; 
            } 
        }
 
        // See IEntityWrapper documentation
        public override bool RequiresScalarChangeTracking
        {
            get { return !(_entity is IEntityWithChangeTracker); } 
        }
 
        // See IEntityWrapper documentation 
        public override bool RequiresAnyChangeTracking
        { 
            get
            {
                Debug.Assert(_entity is IEntityWithRelationships, "Override in subclass should have been called if IEntityWithRelationships not implemented.");
                return RequiresScalarChangeTracking || RequiresComplexChangeTracking; 
            }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK