Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data.Entity / System / Data / EntityClient / EntityAdapter.cs
1 //---------------------------------------------------------------------
2 // <copyright file="EntityAdapter.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner  Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
9 namespace System.Data.EntityClient
10 {
11     using System.Data;
12     using System.Data.Common;
13     using System.Data.Mapping.Update.Internal;
14     using System.Data.Objects;
15     using System.Diagnostics;
16
17     /// <summary>
18     /// Class representing a data adapter for the conceptual layer
19     /// </summary>
20     internal sealed class EntityAdapter : IEntityAdapter
21     {
22         private bool _acceptChangesDuringUpdate = true;
23         private EntityConnection _connection;
24         private Int32? _commandTimeout;
25
26         /// <summary>
27         /// Constructs the EntityAdapter object without a connection object
28         /// </summary>
29         public EntityAdapter()
30         {
31         }
32
33         /// <summary>
34         /// Gets or sets the map connection used by this adapter.
35         /// </summary>
36         DbConnection IEntityAdapter.Connection
37         {
38             get
39             {
40                 return this.Connection;
41             }
42             set
43             {
44                 this.Connection = (EntityConnection)value;
45             }
46         }
47
48         /// <summary>
49         /// Gets or sets the map connection used by this adapter.
50         /// </summary>
51         public EntityConnection Connection
52         {
53             get
54             {
55                 return _connection;
56             }
57             set
58             {
59                 _connection = value;
60             }
61         }
62
63         /// <summary>
64         /// Gets or sets whether the IEntityCache.AcceptChanges should be called during a call to IEntityAdapter.Update.
65         /// </summary>
66         public bool AcceptChangesDuringUpdate
67         {
68             get
69             {
70                 return this._acceptChangesDuringUpdate;
71             }
72             set
73             {
74                 this._acceptChangesDuringUpdate = value;
75             }
76         }
77
78         /// <summary>
79         /// Gets of sets the command timeout for update operations. If null, indicates that the default timeout
80         /// for the provider should be used.
81         /// </summary>
82         Int32? IEntityAdapter.CommandTimeout
83         {
84             get
85             {
86                 return this._commandTimeout;
87             }
88             set
89             {
90                 this._commandTimeout = value;
91             }
92         }
93
94         /// <summary>
95         /// Persist modifications described in the given cache.
96         /// </summary>
97         /// <param name="entityCache">Entity cache containing changes to persist to the store.</param>
98         /// <returns>Number of cache entries affected by the udpate.</returns>
99         public Int32 Update(IEntityStateManager entityCache)
100         {
101             EntityUtil.CheckArgumentNull(entityCache, "entityCache");
102             if (!IsStateManagerDirty(entityCache)) { return 0; }
103
104             // Check that we have a connection before we proceed
105             if (_connection == null)
106             {
107                 throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_NoConnectionForAdapter);
108             }
109
110             // Check that the store connection is available
111             if (_connection.StoreProviderFactory == null || this._connection.StoreConnection == null)
112             {
113                 throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_NoStoreConnectionForUpdate);
114             }
115
116             // Check that the connection is open before we proceed
117             if (ConnectionState.Open != _connection.State)
118             {
119                 throw EntityUtil.InvalidOperation(System.Data.Entity.Strings.EntityClient_ClosedConnectionForUpdate);
120             }
121
122             return UpdateTranslator.Update(entityCache, this);
123         }
124
125         /// <summary>
126         /// Determine whether the cache has changes to apply.
127         /// </summary>
128         /// <param name="entityCache">ObjectStateManager to check. Must not be null.</param>
129         /// <returns>true if cache contains changes entries; false otherwise</returns>
130         private static bool IsStateManagerDirty(IEntityStateManager entityCache)
131         {
132             Debug.Assert(null != entityCache);
133             bool hasChanges = false;
134             // this call to GetCacheEntries is constant time (the ObjectStateManager implementation
135             // maintains an explicit list of entries in each state)
136             foreach (ObjectStateEntry entry in entityCache.GetEntityStateEntries(
137                 EntityState.Added | EntityState.Deleted | EntityState.Modified))
138             {
139                 hasChanges = true;
140                 break;
141             }
142             return hasChanges;
143         }
144     }
145 }