/// <summary> /// Adds an entity in a 'pending insert' state to this table. The added entity will not be observed /// in query results from this table until after SubmitChanges() has been called. Any untracked /// objects referenced directly or transitively by the entity will also be inserted. /// </summary> /// <param name="entity"></param> public void InsertOnSubmit(TEntity entity) { if (entity == null) { throw Error.ArgumentNull("entity"); } CheckReadOnly(); context.CheckNotInSubmitChanges(); context.VerifyTrackingEnabled(); MetaType type = this.metaTable.RowType.GetInheritanceType(entity.GetType()); if (type == null) { throw Error.InheritanceTypeNotRegistered(entity.GetType()); } if (!IsTrackableType(type)) { throw Error.TypeCouldNotBeAdded(type.Type); } TrackedObject tracked = this.context.Services.ChangeTracker.GetTrackedObject(entity); if (tracked == null) { tracked = this.context.Services.ChangeTracker.Track(entity); tracked.ConvertToNew(); } else if (tracked.IsWeaklyTracked) { tracked.ConvertToNew(); } else if (tracked.IsDeleted) { tracked.ConvertToPossiblyModified(); } else if (tracked.IsRemoved) { tracked.ConvertToNew(); } else if (!tracked.IsNew) { throw Error.CantAddAlreadyExistingItem(); } }
public void InsertOnSubmit(TEntity entity) { if ((object)entity == null) { throw System.Data.Linq.Error.ArgumentNull("entity"); } this.CheckReadOnly(); this.context.CheckNotInSubmitChanges(); this.context.VerifyTrackingEnabled(); MetaType inheritanceType = this.metaTable.RowType.GetInheritanceType(entity.GetType()); if (!Table <TEntity> .IsTrackableType(inheritanceType)) { throw System.Data.Linq.Error.TypeCouldNotBeAdded((object)inheritanceType.Type); } TrackedObject trackedObject = this.context.Services.ChangeTracker.GetTrackedObject((object)entity); if (trackedObject == null) { this.context.Services.ChangeTracker.Track((object)entity).ConvertToNew(); } else if (trackedObject.IsWeaklyTracked) { trackedObject.ConvertToNew(); } else if (trackedObject.IsDeleted) { trackedObject.ConvertToPossiblyModified(); } else if (trackedObject.IsRemoved) { trackedObject.ConvertToNew(); } else if (!trackedObject.IsNew) { throw System.Data.Linq.Error.CantAddAlreadyExistingItem(); } }
private void ObserveUntrackedObjects(MetaType type, object item, Dictionary <object, object> visited) { if (!visited.ContainsKey(item)) { visited.Add(item, item); TrackedObject tracked = this._tracker.GetTrackedObject(item); if (tracked == null) { tracked = this._tracker.Track(item); tracked.ConvertToNew(); } else if (tracked.IsDead || tracked.IsRemoved) { // ignore return; } // search parents (objects we are dependent on) foreach (RelatedItem parent in this._services.GetParents(type, item)) { this.ObserveUntrackedObjects(parent.Type, parent.Item, visited); } // synch up primary key unless its generated. if (tracked.IsNew) { if (!tracked.IsPendingGeneration(tracked.Type.IdentityMembers)) { tracked.SynchDependentData(); } } // search children (objects that are dependent on us) foreach (RelatedItem child in this._services.GetChildren(type, item)) { this.ObserveUntrackedObjects(child.Type, child.Item, visited); } } }
private void TrackUntrackedObjects(MetaType type, object item, Dictionary <object, object> visited) { if (!visited.ContainsKey(item)) { visited.Add(item, item); TrackedObject tracked = this._tracker.GetTrackedObject(item); if (tracked == null) { tracked = this._tracker.Track(item); tracked.ConvertToNew(); } else if (tracked.IsDead || tracked.IsRemoved) { // ignore return; } // search parents (objects we are dependent on) foreach (RelatedItem parent in this._services.GetParents(type, item)) { this.TrackUntrackedObjects(parent.Type, parent.Item, visited); } // synch up primary key if (tracked.IsNew) { tracked.InitializeDeferredLoaders(); if (!tracked.IsPendingGeneration(tracked.Type.IdentityMembers)) { tracked.SynchDependentData(); object cached = this._services.InsertLookupCachedObject(tracked.Type, item); if (cached != item) { TrackedObject cachedTracked = this._tracker.GetTrackedObject(cached); Debug.Assert(cachedTracked != null); if (cachedTracked.IsDeleted || cachedTracked.CanInferDelete()) { // adding new object with same ID as object being deleted.. turn into modified tracked.ConvertToPossiblyModified(cachedTracked.Original); // turn deleted to dead... cachedTracked.ConvertToDead(); this._services.RemoveCachedObjectLike(tracked.Type, item); this._services.InsertLookupCachedObject(tracked.Type, item); } else if (!cachedTracked.IsDead) { throw new DuplicateKeyException(item, Strings.CantAddAlreadyExistingKey); } } } else { // we may have a generated PK, however we set the PK on this new item to // match a deleted item object cached = this._services.GetCachedObjectLike(tracked.Type, item); if (cached != null) { TrackedObject cachedTracked = this._tracker.GetTrackedObject(cached); Debug.Assert(cachedTracked != null); if (cachedTracked.IsDeleted || cachedTracked.CanInferDelete()) { // adding new object with same ID as object being deleted.. turn into modified tracked.ConvertToPossiblyModified(cachedTracked.Original); // turn deleted to dead... cachedTracked.ConvertToDead(); this._services.RemoveCachedObjectLike(tracked.Type, item); this._services.InsertLookupCachedObject(tracked.Type, item); } } } } // search children (objects that are dependent on us) foreach (RelatedItem child in this._services.GetChildren(type, item)) { this.TrackUntrackedObjects(child.Type, child.Item, visited); } } }