protected void Update(XElement propertySchema, IEnumerable <T> children, IEnumerable <T> origChildren, UpdateCommandNode <T> updateCommandNode)
        {
            string childrenPath = updateCommandNode.Path + propertySchema.Attribute(SchemaVocab.Name).Value;

            //
            XElement childEntitySchema = GetEntitySchemaByCollection(propertySchema.Attribute(SchemaVocab.Collection).Value);
            string   childEntity       = childEntitySchema.Attribute(SchemaVocab.Name).Value;

            //
            string       relationshipString = propertySchema.Attribute(SchemaVocab.Relationship).Value;
            Relationship childRelationship  = GetParentChildrenRelationship(relationshipString, updateCommandNode.Entity, childEntity);

            if (childRelationship == null)
            {
                return;
            }

            //
            UpdateCommandNodeChildren <T> nodeChildren = new UpdateCommandNodeChildren <T>(childRelationship.DirectRelationships[0], updateCommandNode.Path);

            updateCommandNode.ChildrenCollection.Add(nodeChildren);

            if (childRelationship is ManyToManyRelationship)
            {
                Split(children, origChildren, childEntitySchema, childRelationship as ManyToManyRelationship, updateCommandNode.PropertyValues,
                      childrenPath, updateCommandNode.Entity, updateCommandNode.Schema, nodeChildren.UpdateCommandNodes);
                return;
            }

            //
            XElement childKeySchema         = GetKeySchema(childEntitySchema);
            XElement childConcurrencySchema = GetConcurrencySchema(childEntitySchema);

            //
            int origIndex = 0;

            foreach (T origChild in origChildren)
            {
                UpdateCommandNode <T> origChildCommand = CreateUpdateCommandNode(default(T), origChild, childEntity);
                origChildCommand.EntitySchema         = childEntitySchema;
                origChildCommand.UniqueKeySchema      = childKeySchema;
                origChildCommand.ConcurrencySchema    = childConcurrencySchema;
                origChildCommand.ParentPropertyValues = updateCommandNode.PropertyValues;
                origChildCommand.ParentRelationship   = childRelationship.DirectRelationships[0];
                origChildCommand.Path               = string.Format("{0}[+{1}]", childrenPath, origIndex);
                origChildCommand.PropertyValues     = new Dictionary <string, object>(); // avoid throwing NullReferenceException
                origChildCommand.OrigPropertyValues = GetPropertyValues(origChild, childEntitySchema);
                nodeChildren.UpdateCommandNodes.Add(origChildCommand);
                origIndex++;
            }

            //
            int index = 0;

            foreach (T child in children)
            {
                Dictionary <string, object> childPropertyValues = GetPropertyValues(child, childEntitySchema);

                //
                Dictionary <string, object> childKeyPropertyValues = new Dictionary <string, object>();
                foreach (string property in childKeySchema.Elements(SchemaVocab.Property).Select(x => x.Attribute(SchemaVocab.Name).Value))
                {
                    childKeyPropertyValues.Add(property, childPropertyValues[property]);
                }

                //
                UpdateCommandNode <T> origChildCommandNode = Find(nodeChildren.UpdateCommandNodes, childKeyPropertyValues);
                if (origChildCommandNode == null)
                {
                    Create(child, childEntitySchema, childRelationship.DirectRelationships[0], updateCommandNode.PropertyValues,
                           string.Format("{0}[{1}]", childrenPath, index), childEntity, updateCommandNode.Schema);
                }
                else
                {
                    SetUpdateCommandNode(origChildCommandNode, child);
                    origChildCommandNode.Path           = string.Format("{0}[{1}]", childrenPath, index);
                    origChildCommandNode.PropertyValues = childPropertyValues;

                    // recursive
                    Split(origChildCommandNode);
                }
                index++;
            }

            // delete
            IEnumerable <UpdateCommandNode <T> > deleteNodes = nodeChildren.UpdateCommandNodes.Where(p => p.AggregNode == null);

            foreach (UpdateCommandNode <T> origChildCommand in deleteNodes)
            {
                Delete(origChildCommand.OrigNode, origChildCommand.EntitySchema, origChildCommand.ParentRelationship, origChildCommand.ParentPropertyValues,
                       origChildCommand.Path, origChildCommand.Entity, origChildCommand.Schema);
            }
        }
Beispiel #2
0
        protected UpdateCommandNode <T> Split(T aggregNode, string entity, XElement entitySchema, XElement uniqueKeySchema, XElement concurrencySchema,
                                              DirectRelationship parentRelationship, Dictionary <string, object> parentPropertyValues, string path)
        {
            UpdateCommandNode <T> executeCommand = CreateUpdateCommandNode(aggregNode, entity);

            executeCommand.EntitySchema         = entitySchema;
            executeCommand.UniqueKeySchema      = uniqueKeySchema;
            executeCommand.ConcurrencySchema    = concurrencySchema;
            executeCommand.ParentPropertyValues = parentPropertyValues;
            executeCommand.ParentRelationship   = parentRelationship;
            executeCommand.Path = path;

            executeCommand.PropertyValues = GetPropertyValues(aggregNode, entitySchema);

            //executeCommand.FixedUpdatePropertyValues = new Dictionary<string, object>();

            //
            IEnumerable <KeyValuePair <XElement, T> > propertySchemaChildrens = GetPropertySchemaChildrens(aggregNode, entitySchema);

            foreach (KeyValuePair <XElement, T> childrenPair in propertySchemaChildrens)
            {
                XElement        propertySchema = childrenPair.Key;
                IEnumerable <T> children       = GetChildren(childrenPair.Value);

                //
                string childPath = path + propertySchema.Attribute(SchemaVocab.Name).Value;

                //
                XElement childEntitySchema = GetEntitySchemaByCollection(propertySchema.Attribute(SchemaVocab.Collection).Value);
                string   childEntity       = childEntitySchema.Attribute(SchemaVocab.Name).Value;

                //
                string       relationshipString = propertySchema.Attribute(SchemaVocab.Relationship).Value;
                Relationship childRelationship  = GetParentChildrenRelationship(relationshipString, entity, childEntity);
                if (childRelationship == null)
                {
                    continue;
                }

                //
                UpdateCommandNodeChildren <T> nodeChildren = new UpdateCommandNodeChildren <T>(childRelationship.DirectRelationships[0], path);
                executeCommand.ChildrenCollection.Add(nodeChildren);

                if (childRelationship is ManyToManyRelationship)
                {
                    Split(children, childEntitySchema, childRelationship as ManyToManyRelationship, executeCommand.PropertyValues, childPath, nodeChildren.UpdateCommandNodes);
                }
                else
                {
                    XElement childKeySchema         = GetKeySchema(childEntitySchema);
                    XElement childConcurrencySchema = GetConcurrencySchema(childEntitySchema);

                    int index = 0;
                    foreach (T child in children)
                    {
                        UpdateCommandNode <T> childNode = Split(child, childEntity, childEntitySchema, childKeySchema, childConcurrencySchema,
                                                                childRelationship.DirectRelationships[0], executeCommand.PropertyValues,
                                                                string.Format("{0}[{1}]", childPath, index));
                        nodeChildren.UpdateCommandNodes.Add(childNode);
                        index++;
                    }
                }
            }

            return(executeCommand);
        }