internal List <IDataObject> GetListOfCall(int ID, string propertyName) { ResetState(); List <IStreamable> auxObjects; List <IDataObject> serviceResult = _proxy.GetListOf(_context, _type, ID, propertyName, out auxObjects).ToList(); List <IDataObject> result = new List <IDataObject>(); foreach (IDataObject obj in serviceResult) { result.Add((IDataObject)_context.AttachRespectingIsolationLevel(obj)); } foreach (IPersistenceObject obj in auxObjects) { _context.AttachRespectingIsolationLevel(obj); } _context.PlaybackNotifications(); return(result); }
public int ExchangeObjects(ZetboxContextImpl ctx) { var objectsToSubmit = new List <IPersistenceObject>(); var objectsToAdd = new List <IPersistenceObject>(); var objectsToDetach = new List <IPersistenceObject>(); // Added Objects foreach (var obj in ctx._objects.OfType <PersistenceObjectBaseImpl>() .Where(o => o.ObjectState == DataObjectState.New)) { objectsToSubmit.Add(obj); objectsToAdd.Add(obj); } // Changed objects foreach (var obj in ctx._objects.OfType <PersistenceObjectBaseImpl>() .Where(o => o.ObjectState == DataObjectState.Modified)) { if (!obj.CurrentAccessRights.HasWriteRights()) { throw new System.Security.SecurityException(string.Format("Inconsistent security/rights state detected while changing {0}({1})", ctx.GetInterfaceType(obj).Type.FullName, obj.ID)); } objectsToSubmit.Add(obj); } // Deleted Objects foreach (var obj in ctx._objects.OfType <PersistenceObjectBaseImpl>() .Where(o => o.ObjectState == DataObjectState.Deleted)) { if (!obj.CurrentAccessRights.HasDeleteRights()) { throw new System.Security.SecurityException(string.Format("Inconsistent security/rights state detected while deleting {0}({1})", ctx.GetInterfaceType(obj).Type.FullName, obj.ID)); } // Submit only persisted objects if (Helper.IsPersistedObject(obj)) { objectsToSubmit.Add(obj); } objectsToDetach.Add(obj); } var notifySaveList = objectsToSubmit.OfType <IDataObject>().Where(o => o.ObjectState.In(DataObjectState.New, DataObjectState.Modified)); // Fire PreSave notifySaveList.ForEach(o => o.NotifyPreSave()); var notificationRequests = ctx.AttachedObjects .ToLookup(o => ctx.GetInterfaceType(o)) .Select(g => new ObjectNotificationRequest() { Type = g.Key.ToSerializableType(), IDs = g.Select(o => o.ID).ToArray() }); // Submit to server var objectsFromServer = this.ExecuteServerCall(ctx, objectsToSubmit, notificationRequests); // Apply Changes int counter = 0; var changedObjects = new List <IPersistenceObject>(); foreach (var objFromServer in objectsFromServer) { IClientObject obj; IPersistenceObject underlyingObject; if (counter < objectsToAdd.Count) { obj = (IClientObject)objectsToAdd[counter++]; underlyingObject = obj.UnderlyingObject; // remove object from cache, since index by ID may change. // will be re-inserted on attach later ctx._objects.Remove(underlyingObject); } else { underlyingObject = ctx.ContainsObject(ctx.GetInterfaceType(objFromServer), objFromServer.ID) ?? objFromServer; obj = (IClientObject)underlyingObject; } ctx.RecordNotifications(underlyingObject); if (obj != objFromServer) { underlyingObject.ApplyChangesFrom(objFromServer); } if (objFromServer.ObjectState == DataObjectState.Deleted) { // deleted on server obj.SetDeleted(); } else { // reset ObjectState to new truth obj.SetUnmodified(); } changedObjects.Add(underlyingObject); } objectsToDetach.Except(changedObjects).ForEach(obj => ctx.Detach(obj)); changedObjects.ForEach(obj => ctx.Attach(obj)); this.UpdateModifiedState(ctx); ctx.PlaybackNotifications(); // Fire PostSave notifySaveList.ForEach(o => o.NotifyPostSave()); return(objectsToSubmit.Count); }