protected void Create(T aggreg, XElement entitySchema, DirectRelationship parentRelationship, Dictionary <string, object> parentPropertyValues, string path, string entity, XElement schema) { CreateAggregation <T> createAggregation = CreateCreateAggregation(default(T), entity, schema); createAggregation.Split(aggreg, entitySchema, parentRelationship, parentPropertyValues, path); Commands.AddRange(createAggregation.ExecuteCommands); }
// ManyToMany protected Dictionary <string, object> TransPropertyValues(ManyToManyRelationship relationship, Dictionary <string, object> parent, Dictionary <string, object> child) { Dictionary <string, object> propertyValues = new Dictionary <string, object>(); DirectRelationship firstDirectRelationship = relationship.DirectRelationships[0]; DirectRelationship secondDirectRelationship = relationship.DirectRelationships[1]; for (int i = 0; i < firstDirectRelationship.Properties.Length; i++) { string propertyName = firstDirectRelationship.Properties[i]; string relatedPropertyName = firstDirectRelationship.RelatedProperties[i]; propertyValues.Add(relatedPropertyName, parent[propertyName]); } for (int i = 0; i < secondDirectRelationship.RelatedProperties.Length; i++) { string relatedPropertyName = secondDirectRelationship.RelatedProperties[i]; string propertyName = secondDirectRelationship.Properties[i]; propertyValues.Add(propertyName, child[relatedPropertyName]); } return(propertyValues); }
internal protected void Split(T obj, XElement entitySchema, DirectRelationship parentRelationship, Dictionary <string, object> parentPropertyValues, string path) { string entity = entitySchema.Attribute(SchemaVocab.Name).Value; InsertCommand <T> executeCommand = CreateInsertCommand(obj, entity); executeCommand.EntitySchema = entitySchema; executeCommand.UniqueKeySchema = GetKeySchema(entitySchema); executeCommand.ParentPropertyValues = parentPropertyValues; executeCommand.ParentRelationship = parentRelationship; executeCommand.Path = path; //executeCommand.PropertyValues = GetPropertyValues(executeCommand, out Dictionary<XElement, T> childrenDict); executeCommand.PropertyValues = GetPropertyValues(executeCommand.AggregNode, executeCommand.EntitySchema); SetDefaultValues(executeCommand); Commands.Add(executeCommand); // IEnumerable <KeyValuePair <XElement, T> > propertySchemaChildrens = GetPropertySchemaChildrens(executeCommand.AggregNode, executeCommand.EntitySchema); foreach (KeyValuePair <XElement, T> childrenPair in propertySchemaChildrens) { XElement propertySchema = childrenPair.Key; IEnumerable <T> children = GetChildren(childrenPair.Value); // string childrenPath = 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; } if (childRelationship is ManyToManyRelationship) { Split(children, childEntitySchema, childRelationship as ManyToManyRelationship, executeCommand.PropertyValues, childrenPath); return; } int index = 0; foreach (T child in children) { Split(child, childEntitySchema, childRelationship.DirectRelationships[0], executeCommand.PropertyValues, string.Format("{0}[{1}]", childrenPath, index)); index++; } } }
// ManyToMany protected bool IsDeleteTransSetNull(ManyToManyRelationship relationship) { DirectRelationship firstDirectRelationship = relationship.DirectRelationships[0]; // pure relationship-table if (relationship.DirectRelationships.Length == 2) { DirectRelationship secondDirectRelationship = relationship.DirectRelationships[1]; string relationshipEntity = firstDirectRelationship.RelatedEntity; if (relationshipEntity == secondDirectRelationship.Entity) // assert { List <string> relationshipProperties = new List <string>(firstDirectRelationship.RelatedProperties); relationshipProperties.AddRange(secondDirectRelationship.Properties); XElement entitySchema = Schema.GetEntitySchema(relationshipEntity); List <string> PropertyNames = entitySchema.Elements(SchemaVocab.Property) .Where(x => x.Attribute(SchemaVocab.Column) != null) .Select(x => x.Attribute(SchemaVocab.Name).Value).ToList(); if (PropertyNames.Count == relationshipProperties.Count) { bool pure = true; relationshipProperties.Sort(); PropertyNames.Sort(); for (int i = 0; i < PropertyNames.Count; i++) { if (relationshipProperties[i] == PropertyNames[i]) { continue; } pure = false; } if (pure) { return(false); } } } } // string mmEntity = firstDirectRelationship.RelatedEntity; XElement mmEntitySchema = GetEntitySchema(mmEntity); for (int i = 0; i < firstDirectRelationship.RelatedProperties.Length; i++) { string relatedPropertyName = firstDirectRelationship.RelatedProperties[i]; XElement mmPropertySchema = GetPropertySchema(mmEntitySchema, relatedPropertyName); if (mmPropertySchema.Attribute(SchemaVocab.AllowDBNull).Value == SchemaVocab.True) { return(true); } } return(false); }
protected void Delete(T aggreg, XElement entitySchema, DirectRelationship parentRelationship, Dictionary <string, object> parentPropertyValues, string path, string entity, XElement schema) { DeleteAggregation <T> deleteAggregation = CreateDeleteAggregation(default(T), entity, schema); deleteAggregation.Split(aggreg, entitySchema, parentRelationship, parentPropertyValues, path); // reverse back IEnumerable <ExecuteCommand <T> > executeCommands = deleteAggregation.ExecuteCommands.Reverse(); DeleteCommands.AddRange(executeCommands); }
protected Dictionary <ExpandNode, TempTableNode> CreateChildren(IEnumerable <ExpandNode> qChildren, TempTableNode node, out IEnumerable <string> relatedPropertiesForSelect) { Dictionary <ExpandNode, TempTableNode> childDict = new Dictionary <ExpandNode, TempTableNode>(); List <string> childrenForSelect = new List <string>(); foreach (ExpandNode qChild in qChildren) { TempTableNode child; string[] select = new string[qChild.Query.Select.Properties.Length]; qChild.Query.Select.Properties.CopyTo(select, 0); if (qChild is EntityExpandNode) { child = new EntityTempNode(qChild.Property, select, qChild.Entity); } else if (qChild is CollectionExpandNode) { Order[] orderby = GetOrders(qChild.Query); child = new CollectionTempNode(qChild.Property, select, orderby, qChild.Entity); } else { throw new NotSupportedException(qChild.GetType().ToString()); // never } child.Path = node.Path + "/" + qChild.Property; // DirectRelationship firstDirectRelationship = qChild.Relationship.DirectRelationships[0]; Dictionary <string, string> relatedKey = new Dictionary <string, string>(); for (int i = 0; i < firstDirectRelationship.Properties.Length; i++) { relatedKey.Add(firstDirectRelationship.Properties[i], firstDirectRelationship.RelatedProperties[i]); } child.RelatedKey = relatedKey; node.Children.Add(child); // NativeProperties childrenForSelect.AddRange(firstDirectRelationship.Properties); childDict.Add(qChild, child); } relatedPropertiesForSelect = childrenForSelect.Distinct(); return(childDict); }
// ManyToMany protected XElement TransKeySchema(ManyToManyRelationship relationship, out XElement mmEntitySchema) { DirectRelationship oneToManyRelationship = relationship.DirectRelationships[0]; DirectRelationship manyToOneRelationship = relationship.DirectRelationships[1]; string mmEntity = oneToManyRelationship.RelatedEntity; mmEntitySchema = GetEntitySchema(mmEntity); XElement mmKeySchema = new XElement(mmEntitySchema.Name); IEnumerable <string> mmKeyPropertyNames = oneToManyRelationship.RelatedProperties.Union(manyToOneRelationship.Properties); foreach (string mmPropertyName in mmKeyPropertyNames) { mmKeySchema.Add(mmEntitySchema.Elements(SchemaVocab.Property).First(p => p.Attribute(SchemaVocab.Name).Value == mmPropertyName)); } return(mmKeySchema); }
internal static ForeignKey CreateUndirectedForeignKey(this DirectRelationship relationship, XElement schema) { XElement entitySchema = schema.GetEntitySchema(relationship.Entity); string table = entitySchema.Attribute(SchemaVocab.Table).Value; List <string> columns = new List <string>(); foreach (string property in relationship.Properties) { XElement propertySchema = entitySchema.Elements(SchemaVocab.Property).First(x => x.Attribute(SchemaVocab.Name).Value == property); columns.Add(propertySchema.Attribute(SchemaVocab.Column).Value); } XElement relatedEntitySchema = schema.GetEntitySchema(relationship.RelatedEntity); string relatedTable = relatedEntitySchema.Attribute(SchemaVocab.Table).Value; List <string> relatedColumns = new List <string>(); foreach (string property in relationship.RelatedProperties) { XElement relatedPropertySchema = relatedEntitySchema.Elements(SchemaVocab.Property).First(x => x.Attribute(SchemaVocab.Name).Value == property); relatedColumns.Add(relatedPropertySchema.Attribute(SchemaVocab.Column).Value); } return(new ForeignKey(table, relatedTable, columns, relatedColumns)); }
protected int Execute_Original(UpdateCommandNode <T> node, Modifier <T> modifier) { int affected = Execute(node as UpdateCommand <T>, modifier); if (node.ChildrenCollection.Count == 0) { return(affected); } // foreach (UpdateCommandNodeChildren <T> nodeChildren in node.ChildrenCollection) { string childrenPath = nodeChildren.Path; DirectRelationship relationship = nodeChildren.ParentRelationship; string childEntity = relationship.RelatedEntity; XElement childEntitySchema = node.Schema.GetEntitySchema(childEntity); XElement childKeySchema = SchemaHelper.GetKeySchema(childEntitySchema); Dictionary <string, object> relatedPropertyValues = GetRelatedPropertyValues(relationship, node, out Dictionary <string, object> dbPropertyValues); // IEnumerable <IReadOnlyDictionary <string, object> > refetchedChildPVs = FetchRelatedFromDb(relatedPropertyValues, relationship.RelatedEntity, node.Schema); IEnumerable <IReadOnlyDictionary <string, object> > origChildPVs = nodeChildren.UpdateCommandNodes.Select(n => n.OrigPropertyValues); foreach (IReadOnlyDictionary <string, object> refetchedChildPV in refetchedChildPVs) { Dictionary <string, object> refetchedKeyChildPV = new Dictionary <string, object>(); foreach (string property in childKeySchema.Elements(SchemaVocab.Property).Select(x => x.Attribute(SchemaVocab.Name).Value)) { refetchedKeyChildPV.Add(property, refetchedChildPV[property]); } IReadOnlyDictionary <string, object> found = Find(origChildPVs, refetchedKeyChildPV); if (found == null) { throw new ConstraintException(ErrorMessages.InsertedByAnotherUser); } } // foreach (UpdateCommandNode <T> childNode in nodeChildren.UpdateCommandNodes) { if (childNode.AggregNode == null) { continue; } // establishing relationship foreach (KeyValuePair <string, object> propertyValue in relatedPropertyValues) { if (!childNode.FixedUpdatePropertyValues.ContainsKey(propertyValue.Key)) { childNode.FixedUpdatePropertyValues.Add(propertyValue.Key, propertyValue.Value); } } // Execute_Original(childNode, modifier); } } return(affected); }
public UpdateCommandNodeChildren(DirectRelationship oneToManyRelationship, string path) { ParentRelationship = oneToManyRelationship; Path = path; }
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); }
internal static ForeignKey CreateForeignKey(this DirectRelationship directRelationship, XElement schema) { DirectRelationship relationship = (directRelationship is OneToManyDirectRelationship) ? directRelationship.Reverse() : directRelationship; return(CreateUndirectedForeignKey(relationship, schema)); }
internal protected void Split(IEnumerable <T> children, XElement childEntitySchema, ManyToManyRelationship manyToManyRelationship, Dictionary <string, object> parentPropertyValues, string childrenPath) { string childEntity = childEntitySchema.Attribute(SchemaVocab.Name).Value; XElement mmKeySchema = TransKeySchema(manyToManyRelationship, out XElement mmEntitySchema); string mmEntity = mmEntitySchema.Attribute(SchemaVocab.Name).Value; XElement mmConcurrencySchema = GetConcurrencySchema(mmEntitySchema); // bool mmDeleteTransSetNull = IsDeleteTransSetNull(manyToManyRelationship); Dictionary <string, object> mmUpdatePropertyValues = null; IEnumerable <DirectRelationship> mmRelationships = null; if (mmDeleteTransSetNull) { mmUpdatePropertyValues = new Dictionary <string, object>(); DirectRelationship oneToManyRelationship = manyToManyRelationship.DirectRelationships[0]; for (int i = 0; i < oneToManyRelationship.RelatedProperties.Length; i++) { string relatedPropertyName = oneToManyRelationship.RelatedProperties[i]; mmUpdatePropertyValues.Add(relatedPropertyName, null); } } else { mmRelationships = GetDirectRelationships(mmEntity); } int index = 0; foreach (T child in children) { Dictionary <string, object> childPropertyValues = GetPropertyValues(child, childEntitySchema); Dictionary <string, object> mmPropertyValues = TransPropertyValues(manyToManyRelationship, parentPropertyValues, childPropertyValues); ExecuteCommand <T> mmExecuteCommand; if (mmDeleteTransSetNull) { UpdateCommand <T> mmUpdateCommand = CreateUpdateCommand(child, childEntity); mmUpdateCommand.FixedUpdatePropertyValues = mmUpdatePropertyValues; mmUpdateCommand.ConcurrencySchema = mmConcurrencySchema; mmExecuteCommand = mmUpdateCommand; } else { DeleteCommand <T> mmDeleteCommand = CreateDeleteCommand(child, childEntity); mmDeleteCommand.ConcurrencySchema = mmConcurrencySchema; mmDeleteCommand.ChildRelationships = mmRelationships; mmExecuteCommand = mmDeleteCommand; } mmExecuteCommand.EntitySchema = mmEntitySchema; mmExecuteCommand.UniqueKeySchema = mmKeySchema; mmExecuteCommand.PropertyValues = mmPropertyValues; mmExecuteCommand.ParentPropertyValues = parentPropertyValues; mmExecuteCommand.ParentRelationship = manyToManyRelationship.DirectRelationships[0]; mmExecuteCommand.Path = string.Format("{0}[{1}]", childrenPath, index); Commands.Add(mmExecuteCommand); index++; } }