protected internal virtual void PutInternal(CachedDbEntity entityToAdd) { var type = entityToAdd.Entity.GetType(); var cacheKey = CacheKeyMapping.GetEntityCacheKey(type); IDictionary <string, CachedDbEntity> map = CachedEntites.ContainsKey(cacheKey) ? CachedEntites[cacheKey] : null; if (map == null) { map = new Dictionary <string, CachedDbEntity>(); CachedEntites[cacheKey] = map; } if (entityToAdd.Entity.Id == null) { entityToAdd.Entity.Id = context.Impl.Context.CommandContext.Scope.Resolve <IDGenerator>().NextId; } // check whether this object is already present in the cache var existingCachedEntity = map.ContainsKey(entityToAdd.Entity.Id) ? map[entityToAdd.Entity.Id] : null; if (existingCachedEntity == null) { map[entityToAdd.Entity.Id] = entityToAdd; } else { switch (entityToAdd.EntityState) { case DbEntityState.Transient: // cannot put TRANSIENT entity if entity with same id already exists in cache. if (existingCachedEntity.EntityState == DbEntityState.Transient) { throw Log.EntityCacheDuplicateEntryException("TRANSIENT", entityToAdd.Entity.Id, entityToAdd.Entity.GetType(), existingCachedEntity.EntityState); } throw Log.AlreadyMarkedEntityInEntityCacheException(entityToAdd.Entity.Id, entityToAdd.Entity.GetType(), existingCachedEntity.EntityState); case DbEntityState.Persistent: if (existingCachedEntity.EntityState == DbEntityState.Persistent) { // use new entity state, replacing the existing one. map[entityToAdd.Entity.Id] = entityToAdd; break; } if ((existingCachedEntity.EntityState == DbEntityState.DeletedPersistent) || (existingCachedEntity.EntityState == DbEntityState.DeletedMerged)) { break; } // otherwise fail: throw Log.EntityCacheDuplicateEntryException("PERSISTENT", entityToAdd.Entity.Id, entityToAdd.Entity.GetType(), existingCachedEntity.EntityState); case DbEntityState.Merged: if ((existingCachedEntity.EntityState == DbEntityState.Persistent) || (existingCachedEntity.EntityState == DbEntityState.Merged)) { // use new entity state, replacing the existing one. map[entityToAdd.Entity.Id] = entityToAdd; break; } if ((existingCachedEntity.EntityState == DbEntityState.DeletedPersistent) || (existingCachedEntity.EntityState == DbEntityState.DeletedMerged)) { break; } // otherwise fail: throw Log.EntityCacheDuplicateEntryException("MERGED", entityToAdd.Entity.Id, entityToAdd.Entity.GetType(), existingCachedEntity.EntityState); default: // deletes are always added map[entityToAdd.Entity.Id] = entityToAdd; break; } } }