@@ -79,6 +79,24 @@ internal void EnsureDeleted()
7979 InMemoryCache < TEntity , TKey > . Instance . GetContext ( DatabaseName ) . Clear ( ) ;
8080 }
8181
82+ /// <summary>
83+ /// Sets the time stamp.
84+ /// </summary>
85+ /// <param name="time">The time.</param>
86+ internal void SetTimeStamp ( DateTime time )
87+ {
88+ InMemoryCache < TEntity , TKey > . Instance . SetTimeStamp ( DatabaseName , time ) ;
89+ }
90+
91+ /// <summary>
92+ /// Gets the time stamp.
93+ /// </summary>
94+ /// <returns>The time stamp.</returns>
95+ internal DateTime GetTimeStamp ( )
96+ {
97+ return InMemoryCache < TEntity , TKey > . Instance . GetTimeStamp ( DatabaseName ) ;
98+ }
99+
82100 #endregion
83101
84102 #region Private Methods
@@ -146,17 +164,23 @@ protected override void AddItem(TEntity entity)
146164 . Select ( x => x . Key )
147165 . SingleOrDefault ( ) ;
148166
167+ var hasTemporaryKey = false ;
168+
149169 if ( key != null && key . Equals ( default ( TKey ) ) )
150170 {
151171 key = GetPrimaryKey ( entity ) ;
152172
153173 if ( key != null && key . Equals ( default ( TKey ) ) )
154174 {
155175 key = GenerateTemporaryPrimaryKey ( ) ;
176+ hasTemporaryKey = true ;
156177 }
157178 }
158179
159- _context [ key ] = new EntitySet < TEntity , TKey > ( entity , key , EntityState . Added ) ;
180+ _context [ key ] = new EntitySet < TEntity , TKey > ( entity , key , EntityState . Added )
181+ {
182+ HasTemporaryKey = hasTemporaryKey
183+ } ;
160184 }
161185
162186 /// <summary>
@@ -165,13 +189,18 @@ protected override void AddItem(TEntity entity)
165189 protected override void DeleteItem ( TEntity entity )
166190 {
167191 var key = GetPrimaryKey ( entity ) ;
192+ var hasTemporaryKey = false ;
168193
169194 if ( key != null && key . Equals ( default ( TKey ) ) )
170195 {
171196 key = GenerateTemporaryPrimaryKey ( ) ;
197+ hasTemporaryKey = true ;
172198 }
173199
174- _context [ key ] = new EntitySet < TEntity , TKey > ( entity , key , EntityState . Removed ) ;
200+ _context [ key ] = new EntitySet < TEntity , TKey > ( entity , key , EntityState . Removed )
201+ {
202+ HasTemporaryKey = hasTemporaryKey
203+ } ;
175204 }
176205
177206 /// <summary>
@@ -180,13 +209,18 @@ protected override void DeleteItem(TEntity entity)
180209 protected override void UpdateItem ( TEntity entity )
181210 {
182211 var key = GetPrimaryKey ( entity ) ;
212+ var hasTemporaryKey = false ;
183213
184214 if ( key != null && key . Equals ( default ( TKey ) ) )
185215 {
186216 key = GenerateTemporaryPrimaryKey ( ) ;
217+ hasTemporaryKey = true ;
187218 }
188219
189- _context [ key ] = new EntitySet < TEntity , TKey > ( entity , key , EntityState . Modified ) ;
220+ _context [ key ] = new EntitySet < TEntity , TKey > ( entity , key , EntityState . Modified )
221+ {
222+ HasTemporaryKey = hasTemporaryKey
223+ } ;
190224 }
191225
192226 /// <summary>
@@ -200,36 +234,37 @@ protected override void SaveChanges()
200234
201235 foreach ( var entitySet in _context . Select ( y => y . Value ) )
202236 {
203- var temporaryKey = entitySet . Key ;
204- var key = GetPrimaryKey ( entitySet . Entity ) ;
237+ var key = entitySet . Key ;
205238
206239 if ( entitySet . State == EntityState . Added )
207240 {
208- if ( key == null || key . Equals ( default ( TKey ) ) )
241+ if ( entitySet . HasTemporaryKey )
209242 {
210243 key = GeneratePrimaryKey ( ) ;
211244 SetPrimaryKey ( entitySet . Entity , key ) ;
212245 }
213- else if ( context . ContainsKey ( temporaryKey ) )
246+ else if ( context . ContainsKey ( key ) )
214247 {
215248 throw new InvalidOperationException ( string . Format ( CultureInfo . CurrentCulture , Resources . EntityAlreadyBeingTrackedInStore , entitySet . Entity . GetType ( ) ) ) ;
216249 }
217250 }
218- else if ( ! context . ContainsKey ( temporaryKey ) )
251+ else if ( ! context . ContainsKey ( key ) )
219252 {
220253 throw new InvalidOperationException ( Resources . EntityNotFoundInStore ) ;
221254 }
222255
223256 if ( entitySet . State == EntityState . Removed )
224257 {
225- context . Remove ( temporaryKey ) ;
258+ context . Remove ( key ) ;
226259 }
227260 else
228261 {
229262 context [ key ] = DeepCopy ( entitySet . Entity ) ;
230263 }
231264 }
232265
266+ SetTimeStamp ( DateTime . Now ) ;
267+
233268 _context . Clear ( ) ;
234269 }
235270 }
@@ -241,8 +276,8 @@ protected override IQueryable<TEntity> GetQuery(IFetchStrategy<TEntity> fetchStr
241276 {
242277 return InMemoryCache < TEntity , TKey > . Instance
243278 . GetContext ( DatabaseName )
244- . AsQueryable ( )
245- . Select ( y => y . Value ) ;
279+ . Select ( y => y . Value )
280+ . AsQueryable ( ) ;
246281 }
247282
248283 /// <summary>
@@ -300,6 +335,11 @@ public EntitySet(TEntity entity, TKey key, EntityState state)
300335 /// </summary>
301336 public EntityState State { get ; }
302337
338+ /// <summary>
339+ /// Gets or sets a value indicating whether this instance has a temporary key.
340+ /// </summary>
341+ public bool HasTemporaryKey { get ; set ; }
342+
303343 #endregion
304344 }
305345
@@ -314,8 +354,7 @@ private enum EntityState
314354 {
315355 Added ,
316356 Removed ,
317- Modified ,
318- Unchanged
357+ Modified
319358 }
320359
321360 #endregion
@@ -333,6 +372,7 @@ private class InMemoryCache<TEntity, TKey> where TEntity : class
333372 private static volatile InMemoryCache < TEntity , TKey > _instance ;
334373 private static readonly object _syncRoot = new object ( ) ;
335374 private readonly ConcurrentDictionary < string , SortedDictionary < TKey , TEntity > > _storage ;
375+ private readonly ConcurrentDictionary < string , DateTime > _timestamp ;
336376
337377 #endregion
338378
@@ -344,6 +384,7 @@ private class InMemoryCache<TEntity, TKey> where TEntity : class
344384 private InMemoryCache ( )
345385 {
346386 _storage = new ConcurrentDictionary < string , SortedDictionary < TKey , TEntity > > ( ) ;
387+ _timestamp = new ConcurrentDictionary < string , DateTime > ( ) ;
347388 }
348389
349390 #endregion
@@ -389,6 +430,28 @@ public SortedDictionary<TKey, TEntity> GetContext(string name)
389430 return _storage [ name ] ;
390431 }
391432
433+ /// <summary>
434+ /// Sets the time stamp.
435+ /// </summary>
436+ /// <param name="name">The database name.</param>
437+ /// <param name="time">The time.</param>
438+ public void SetTimeStamp ( string name , DateTime time )
439+ {
440+ _timestamp [ name ] = time ;
441+ }
442+
443+ /// <summary>
444+ /// Gets the time stamp.
445+ /// </summary>
446+ /// <param name="name">The database name.</param>
447+ /// <returns>The time stamp.</returns>
448+ public DateTime GetTimeStamp ( string name )
449+ {
450+ _timestamp . TryGetValue ( name , out DateTime time ) ;
451+
452+ return time ;
453+ }
454+
392455 #endregion
393456 }
394457
0 commit comments