public virtual DataAccessObject EvictObject(DataAccessObject value)
        {
            var typeHandle = Type.GetTypeHandle(value);

            if ((value.GetAdvanced().ObjectState & DataAccessObjectState.Untracked) == DataAccessObjectState.Untracked)
            {
                return(value);
            }

            if (!this.cachesByType.TryGetValue(typeHandle, out var cache))
            {
                if (this.isCommiting)
                {
                    Logger.Debug($"Skipping eviction of object {value.GetType()} because commit in process");

                    return(value);
                }

                cache = CreateCacheForDataAccessObject(value, this);

                this.cachesByType[typeHandle] = cache;
            }

            cache.Evict(value);

            return(value);
        }
예제 #2
0
            public DataAccessObject <T> Cache(DataAccessObject <T> value, bool forImport)
            {
                if (this.dataAccessObjectDataContext.isCommiting)
                {
                    return(value);
                }

                var dataAccessObject = (DataAccessObject)value;

                var type = value.GetType();

                if (dataAccessObject.GetAdvanced().IsNew)
                {
                    HashSet <DataAccessObject> notReadyForCommitSubcache;

                    if (dataAccessObject.GetAdvanced().PrimaryKeyIsCommitReady)
                    {
                        Dictionary <DataAccessObject, DataAccessObject> subcache;

                        if (!this.newObjects.TryGetValue(type, out subcache))
                        {
                            subcache = new Dictionary <DataAccessObject, DataAccessObject>(DataAccessObjectServerSidePropertiesAccountingComparer.Default);

                            this.newObjects[type] = subcache;
                        }

                        DataAccessObject result;

                        if (subcache.TryGetValue(value, out result))
                        {
                            if (result != value)
                            {
                                throw new ObjectAlreadyExistsException(value, null, null);
                            }
                        }

                        subcache[value] = value;

                        if (this.objectsNotReadyForCommit.TryGetValue(type, out notReadyForCommitSubcache))
                        {
                            notReadyForCommitSubcache.Remove(value);
                        }

                        if (dataAccessObject.GetAdvanced().NumberOfPrimaryKeysGeneratedOnServerSide > 0)
                        {
                            return(value);
                        }
                    }
                    else
                    {
                        if (!this.objectsNotReadyForCommit.TryGetValue(type, out notReadyForCommitSubcache))
                        {
                            notReadyForCommitSubcache = new HashSet <DataAccessObject>(ObjectReferenceIdentityEqualityComparer <IDataAccessObjectAdvanced> .Default);

                            this.objectsNotReadyForCommit[type] = notReadyForCommitSubcache;
                        }

                        if (!notReadyForCommitSubcache.Contains(value))
                        {
                            notReadyForCommitSubcache.Add(value);
                        }

                        return(value);
                    }
                }

                if (dataAccessObject.GetAdvanced().IsMissingAnyDirectOrIndirectServerSideGeneratedPrimaryKeys)
                {
                    return(value);
                }

                if (dataAccessObject.GetAdvanced().NumberOfPrimaryKeys > 1)
                {
                    Dictionary <CompositePrimaryKey, DataAccessObject> subcache;

                    var key = new CompositePrimaryKey(value.GetAdvanced().GetPrimaryKeys());

                    if (this.objectsByIdCacheComposite == null)
                    {
                        this.objectsByIdCacheComposite = new Dictionary <Type, Dictionary <CompositePrimaryKey, DataAccessObject> >(PrimeNumbers.Prime127);
                    }

                    if (!this.objectsByIdCacheComposite.TryGetValue(type, out subcache))
                    {
                        subcache = new Dictionary <CompositePrimaryKey, DataAccessObject>(PrimeNumbers.Prime127, CompositePrimaryKeyComparer.Default);

                        this.objectsByIdCacheComposite[type] = subcache;
                    }

                    if (!forImport)
                    {
                        DataAccessObject outValue;

                        if (subcache.TryGetValue(key, out outValue))
                        {
                            var deleted = outValue.IsDeleted();

                            outValue.ToObjectInternal().SwapData(value, true);

                            if (deleted)
                            {
                                outValue.ToObjectInternal().SetIsDeleted(true);
                            }

                            return((DataAccessObject <T>)outValue);
                        }
                    }

                    if (this.objectsDeletedComposite != null)
                    {
                        Dictionary <CompositePrimaryKey, DataAccessObject> subList;

                        if (this.objectsDeletedComposite.TryGetValue(type, out subList))
                        {
                            DataAccessObject existingDeleted;

                            if (subList.TryGetValue(key, out existingDeleted))
                            {
                                if (!forImport)
                                {
                                    existingDeleted.ToObjectInternal().SwapData(value, true);
                                    existingDeleted.ToObjectInternal().SetIsDeleted(true);

                                    return((DataAccessObject <T>)existingDeleted);
                                }
                                else
                                {
                                    if (value.IsDeleted())
                                    {
                                        subList[key] = value;
                                    }
                                    else
                                    {
                                        subList.Remove(key);
                                        subcache[key] = value;
                                    }

                                    return(value);
                                }
                            }
                        }
                    }

                    subcache[key] = value;

                    return(value);
                }
                else
                {
                    var id = value.Id;
                    Dictionary <T, DataAccessObject> subcache;

                    if (!this.objectsByIdCache.TryGetValue(type, out subcache))
                    {
                        subcache = new Dictionary <T, DataAccessObject>(PrimeNumbers.Prime127);

                        this.objectsByIdCache[type] = subcache;
                    }

                    if (!forImport)
                    {
                        DataAccessObject outValue;

                        if (subcache.TryGetValue(id, out outValue))
                        {
                            var deleted = outValue.IsDeleted();

                            outValue.ToObjectInternal().SwapData(value, true);

                            if (deleted)
                            {
                                outValue.ToObjectInternal().SetIsDeleted(true);
                            }

                            return((DataAccessObject <T>)outValue);
                        }
                    }

                    if (this.objectsDeleted != null)
                    {
                        Dictionary <T, DataAccessObject> subList;

                        if (this.objectsDeleted.TryGetValue(type, out subList))
                        {
                            DataAccessObject existingDeleted;

                            if (subList.TryGetValue(id, out existingDeleted))
                            {
                                if (!forImport)
                                {
                                    existingDeleted.ToObjectInternal().SwapData(value, true);
                                    existingDeleted.ToObjectInternal().SetIsDeleted(true);

                                    return((DataAccessObject <T>)existingDeleted);
                                }
                                else
                                {
                                    if (value.IsDeleted())
                                    {
                                        subList[id] = value;
                                    }
                                    else
                                    {
                                        subList.Remove(id);
                                        subcache[id] = value;
                                    }

                                    return(value);
                                }
                            }
                        }
                    }

                    subcache[value.Id] = value;

                    return(value);
                }
            }
예제 #3
0
            public void Deleted(DataAccessObject <T> value)
            {
                var type = value.GetType();

                if (((IDataAccessObjectAdvanced)value).IsNew)
                {
                    HashSet <DataAccessObject> notReadyForCommitSubcache;
                    Dictionary <DataAccessObject, DataAccessObject> subcache;

                    if (this.newObjects.TryGetValue(type, out subcache))
                    {
                        subcache.Remove(value);
                    }

                    if (this.objectsNotReadyForCommit.TryGetValue(type, out notReadyForCommitSubcache))
                    {
                        notReadyForCommitSubcache.Remove(value);
                    }
                }
                else
                {
                    if (((IDataAccessObjectAdvanced)value).NumberOfPrimaryKeys > 1)
                    {
                        Dictionary <CompositePrimaryKey, DataAccessObject> subcache;
                        var key = new CompositePrimaryKey(value.GetAdvanced().GetPrimaryKeys());

                        if (this.objectsByIdCacheComposite == null)
                        {
                            return;
                        }

                        if (!this.objectsByIdCacheComposite.TryGetValue(type, out subcache))
                        {
                            return;
                        }

                        subcache.Remove(key);

                        Dictionary <CompositePrimaryKey, DataAccessObject> subList;

                        if (this.objectsDeletedComposite == null)
                        {
                            this.objectsDeletedComposite = new Dictionary <Type, Dictionary <CompositePrimaryKey, DataAccessObject> >(PrimeNumbers.Prime67);
                        }

                        if (!this.objectsDeletedComposite.TryGetValue(type, out subList))
                        {
                            subList = new Dictionary <CompositePrimaryKey, DataAccessObject>(PrimeNumbers.Prime67, CompositePrimaryKeyComparer.Default);

                            this.objectsDeletedComposite[type] = subList;
                        }

                        subList[key] = value;
                    }
                    else
                    {
                        Dictionary <T, DataAccessObject> subcache;

                        if (!this.objectsByIdCache.TryGetValue(type, out subcache))
                        {
                            return;
                        }

                        subcache.Remove(value.Id);

                        Dictionary <T, DataAccessObject> subList;

                        if (this.objectsDeleted == null)
                        {
                            this.objectsDeleted = new Dictionary <Type, Dictionary <T, DataAccessObject> >(PrimeNumbers.Prime67);
                        }

                        if (!this.objectsDeleted.TryGetValue(type, out subList))
                        {
                            subList = new Dictionary <T, DataAccessObject>(PrimeNumbers.Prime127);

                            this.objectsDeleted[type] = subList;
                        }

                        subList[value.Id] = value;
                    }
                }
            }