//--------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- namespace System.Data.EntityClient { using System.Data; using System.Data.Common; using System.Data.Mapping.Update.Internal; using System.Data.Objects; using System.Diagnostics; /// /// Class representing a data adapter for the conceptual layer /// internal sealed class EntityAdapter : IEntityAdapter { private bool _acceptChangesDuringUpdate = true; private EntityConnection _connection; private Int32? _commandTimeout; /// /// Constructs the EntityAdapter object without a connection object /// public EntityAdapter() { } /// /// Gets or sets the map connection used by this adapter. /// DbConnection IEntityAdapter.Connection { get { return this.Connection; } set { this.Connection = (EntityConnection)value; } } /// /// Gets or sets the map connection used by this adapter. /// public EntityConnection Connection { get { return _connection; } set { _connection = value; } } /// /// Gets or sets whether the IEntityCache.AcceptChanges should be called during a call to IEntityAdapter.Update. /// public bool AcceptChangesDuringUpdate { get { return this._acceptChangesDuringUpdate; } set { this._acceptChangesDuringUpdate = value; } } /// /// Gets of sets the command timeout for update operations. If null, indicates that the default timeout /// for the provider should be used. /// Int32? IEntityAdapter.CommandTimeout { get { return this._commandTimeout; } set { this._commandTimeout = value; } } /// /// Persist modifications described in the given cache. /// /// Entity cache containing changes to persist to the store. /// Number of cache entries affected by the udpate. public Int32 Update(IEntityStateManager entityCache) { EntityUtil.CheckArgumentNull(entityCache, "entityCache"); if (!IsStateManagerDirty(entityCache)) { return 0; } // Check that we have a connection before we proceed if (_connection == null) { throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_NoConnectionForAdapter); } // Check that the store connection is available if (_connection.StoreProviderFactory == null || this._connection.StoreConnection == null) { throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_NoStoreConnectionForUpdate); } // Check that the connection is open before we proceed if (ConnectionState.Open != _connection.State) { throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_ClosedConnectionForUpdate); } return UpdateTranslator.Update(entityCache, this); } /// /// Determine whether the cache has changes to apply. /// /// ObjectStateManager to check. Must not be null. /// true if cache contains changes entries; false otherwise private static bool IsStateManagerDirty(IEntityStateManager entityCache) { Debug.Assert(null != entityCache); bool hasChanges = false; // this call to GetCacheEntries is constant time (the ObjectStateManager implementation // maintains an explicit list of entries in each state) foreach (ObjectStateEntry entry in entityCache.GetEntityStateEntries( EntityState.Added | EntityState.Deleted | EntityState.Modified)) { hasChanges = true; break; } return hasChanges; } } }