Exemple #1
0
            protected override IEnumerable <IPersistenceObject> ExecuteServerCall(ZetboxContextImpl ctx, IEnumerable <IPersistenceObject> objectsToSubmit, IEnumerable <ObjectNotificationRequest> notificationRequests)
            {
                IEnumerable <IPersistenceObject> changedObjects;
                List <IStreamable> auxObjects;

                Result = ctx.proxy.InvokeServerMethod(
                    ctx,
                    ctx.GetInterfaceType(obj),
                    obj.ID,
                    name,
                    retValType,
                    parameterTypes,
                    parameter,
                    objectsToSubmit,
                    notificationRequests,
                    out changedObjects,
                    out auxObjects);

                if (Result != null && Result.GetType().IsIPersistenceObject())
                {
                    Result = ctx.AttachRespectingIsolationLevel((IPersistenceObject)Result);
                }
                else if (Result != null && Result.GetType().IsIList() && Result.GetType().FindElementTypes().Any(t => t.IsIPersistenceObject()))
                {
                    var lst = (IList)Result;
                    for (int i = 0; i < lst.Count; i++)
                    {
                        lst[i] = ctx.AttachRespectingIsolationLevel((IPersistenceObject)lst[i]);
                    }
                }

                if (auxObjects != null)
                {
                    foreach (IPersistenceObject auxObj in auxObjects)
                    {
                        ctx.AttachRespectingIsolationLevel(auxObj);
                    }
                }

                return(changedObjects);
            }
Exemple #2
0
            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);
            }