public override KeyExpressions GetExistingAssociatedKeys(ResourceContainer resourceContainer, ResourceProperty property, KeyExpression keyExpression) { bool pageSizeChanged = false; int originalPageSize = this.DataService.ConfigSettings.GetEntitySetPageSize(resourceContainer.Name); if (originalPageSize < 1000) { pageSizeChanged = true; this.DataService.ConfigSettings.SetEntitySetPageSize(resourceContainer.Name, 100000); } UriQueryBuilder uriQueryBuilder = new UriQueryBuilder(this, this.ServiceUri); ExpNode query = Query.From( Exp.Variable(resourceContainer)) .Where(keyExpression) //.OfType(property.ResourceType) .Nav(new PropertyExpression(property)) .Select(); string uri = uriQueryBuilder.Build(query); ResourceType associatedResourceType = property.Type as ResourceType; if (property.Type is CollectionType) { associatedResourceType = (property.Type as CollectionType).SubType as ResourceType; } Type type = this._resourceTypeToWorkspaceTypeList[associatedResourceType]; MethodInfo method = this.GetType().GetMethod("ClientExecuteWrapper", new Type[] { typeof(string), typeof(ResourceContainer) }); MethodInfo genMethod = method.MakeGenericMethod(new Type[] { type }); IEnumerable o = (IEnumerable)genMethod.Invoke(this, new object[] { uri, resourceContainer.FindDefaultRelatedContainer(property) }); KeyExpressions keys = new KeyExpressions(); //IEnumerator enumerator = o.GetEnumerator(); foreach (object current in o) { if (current != null) { //Type t = enumerator.Current.GetType(); Type t = current.GetType(); IEnumerable <ResourceType> typesWithName = this.ServiceContainer.ResourceTypes.Where(rt => (t.Name.Equals(rt.Name))); IEnumerable <ResourceType> typesWithNamespace = typesWithName.Where(rt2 => rt2.Namespace == t.Namespace).ToList(); ResourceType instanceType = typesWithNamespace.First(); ResourceContainer relatedContainer = resourceContainer.FindDefaultRelatedContainer(property); keys.Add(GetKeyExpression(relatedContainer, instanceType, current)); } } if (pageSizeChanged) { this.DataService.ConfigSettings.SetEntitySetPageSize(resourceContainer.Name, originalPageSize); } return(keys); }
private static List <ResourceInstanceProperty> CloneRequiredRelationships(ResourceContainer container, ResourceType resourceType, KeyExpression keyExpression) { List <ResourceInstanceProperty> properties = new List <ResourceInstanceProperty>(); //Foreach Navigation Property in dataObject create a bind Dictionary <ResourceProperty, KeyExpressions> navigationProperties = GetAllAssociatedKeys(container, resourceType, keyExpression); foreach (ResourceProperty navProperty in navigationProperties.Keys) { //ResourceAssociationEnd otherEnd = navProperty.ResourceAssociation.GetOtherEnd(navProperty); ResourceType navPropertyResourceType = (navProperty.Type is CollectionType ? (navProperty.Type as CollectionType).SubType : navProperty.Type) as ResourceType; ResourceContainer otherContainer = container.FindDefaultRelatedContainer(navProperty); bool foreignKeyViolation = false; foreach (ResourceProperty otherProperty in otherContainer.BaseType.Key.Properties) { if (otherProperty.ForeignKeys.Count() > 0) { ResourceType otherType = otherProperty.ForeignKeys.First().PrimaryKey.Properties.OfType <ResourceProperty>().First().ResourceType; if (otherType == container.BaseType) { foreignKeyViolation = true; break; } } } if (foreignKeyViolation) { continue; } KeyExpressions keyExpressions = navigationProperties[navProperty]; if (navProperty.Type is ResourceType) { if (keyExpressions.Count > 0) { properties.Add(CreateRefInstanceProperty(keyExpressions[0], otherContainer, navProperty)); } } else { ResourceInstanceProperty property = CreateCollectionInstanceProperty(keyExpressions, otherContainer, navProperty); if (property != null) { properties.Add(property); } } } return(properties); }
private void InsertData(ResourceContainer container, int count) { ResourceContainer currentContainer; ResourceType currentType; KeyExpression currentKey; KeyedResourceInstance currentEntity; KeyedResourceInstance parentEntity; Queue <object[]> queue = new Queue <object[]>(); foreach (ResourceType resourceType in container.ResourceTypes) { if (resourceType.Facets.AbstractType) { continue; } for (int i = 0; i < count; i++) { if (CreateKeyedResourceInstance(container, resourceType, out currentKey, out currentEntity)) { DataInserter.AddEntity(currentKey, currentEntity); queue.Enqueue(new object[] { currentKey, currentEntity, null }); } } } HashSet <ResourceType> typesAdded = new HashSet <ResourceType>(); while (queue.Count > 0) { object[] current = queue.Dequeue(); currentKey = current[0] as KeyExpression; currentEntity = current[1] as KeyedResourceInstance; parentEntity = current[2] as KeyedResourceInstance; currentContainer = currentKey.ResourceContainer; currentType = currentKey.ResourceType; typesAdded.Add(currentType); foreach (ResourceProperty property in currentType.Properties.OfType <ResourceProperty>().Where(p => p.IsNavigation)) { ResourceContainer propertyResourceContainer = container.FindDefaultRelatedContainer(property); ResourceType propertyResourceType = property.OtherAssociationEnd.ResourceType; List <ResourceType> possibleTypes = new List <ResourceType>() { propertyResourceType }; possibleTypes.AddRange(propertyResourceType.DerivedTypes); int typeOffset = AstoriaTestProperties.Random.Next(possibleTypes.Count); bool collection = (property.Type is CollectionType); int linked = 1; if (collection) { linked = Math.Max(possibleTypes.Count, 2); } if (!collection && parentEntity != null && parentEntity.TypeName == propertyResourceType.Name) { DataInserter.AddAssociation(currentEntity, property, parentEntity); continue; } for (int i = 0; i < linked; i++) { ResourceType typeToAdd = possibleTypes[(i + typeOffset) % possibleTypes.Count]; if (!typesAdded.Contains(typeToAdd)) { // add and link new entity KeyedResourceInstance childEntity; KeyExpression childKey; if (CreateKeyedResourceInstance(propertyResourceContainer, typeToAdd, out childKey, out childEntity)) { // add new entity DataInserter.AddEntity(childKey, childEntity); // add it to the queue queue.Enqueue(new object[] { childKey, childEntity, currentEntity }); // add to collection DataInserter.AddAssociation(currentEntity, property, childEntity); } } else if (property.OtherAssociationEnd.Multiplicity == Multiplicity.Many) { // link existing entity ResourceContainer otherContainer = container.FindDefaultRelatedContainer(property); KeyExpression otherKey = this.GetRandomGeneratedKey(otherContainer, typeToAdd); if (otherKey != null) { KeyedResourceInstance otherEntity; if (_existingEntityMap.TryGetValue(otherKey, out otherEntity)) { DataInserter.AddAssociation(currentEntity, property, otherEntity); } } } } // end of this property } // end of this entity } DataInserter.Flush(); }
private static ResourceInstanceKey TryCreateUniqueResourceInstanceKey(ResourceContainer container, ResourceType resType, KeyExpressions relatedForeignKeys) { Workspace workspace = container.Workspace; List <ResourceInstanceSimpleProperty> keyProperties = new List <ResourceInstanceSimpleProperty>(); Dictionary <ResourceProperty, ResourceProperty> foreignKeyMap = resType.Key.Properties.OfType <ResourceProperty>() .Where(p => p.ForeignKeys.Any()) .ToDictionary(p => p, p => p.ForeignKeys.First().PrimaryKey.Properties.OfType <ResourceProperty>().First()); Dictionary <string, ResourceProperty> reverseForeignKeyMap = new Dictionary <string, ResourceProperty>(); foreach (KeyValuePair <ResourceProperty, ResourceProperty> pair in foreignKeyMap) { reverseForeignKeyMap[pair.Value.Name] = pair.Key; } Dictionary <ResourceProperty, object> propertyValues = new Dictionary <ResourceProperty, object>(); List <ResourceProperty> constrainedProperties = new List <ResourceProperty>(); foreach (ResourceProperty property in resType.Key.Properties.OfType <ResourceProperty>()) { if (foreignKeyMap.ContainsKey(property)) { constrainedProperties.Add(property); } else { NodeValue obj = (property.Type as PrimitiveType).CreateRandomValueForFacets(property.Facets); propertyValues[property] = obj.ClrValue; } } foreach (ResourceProperty currentProperty in constrainedProperties) { if (propertyValues.ContainsKey(currentProperty)) { continue; } ResourceProperty foreignProperty = foreignKeyMap[currentProperty]; ResourceContainer foreignContainer = container.FindDefaultRelatedContainer(foreignProperty.ResourceType); KeyExpression foreignKey = relatedForeignKeys.Where(k => k.ResourceContainer == foreignContainer).FirstOrDefault(); if (foreignKey == null) { KeyExpressions foreignKeys = workspace.GetAllExistingKeysOfType(foreignContainer, foreignProperty.ResourceType); while (foreignKey == null && foreignKeys.Any()) { foreignKey = foreignKeys.Choose(); // ensure that for every property in the key, it matches any local values for (int i = 0; i < foreignKey.Properties.Length; i++) { string keyPropertyName = foreignKey.Properties[i].Name; ResourceProperty localProperty; if (reverseForeignKeyMap.TryGetValue(keyPropertyName, out localProperty)) { object keyValue = foreignKey.Values[i].ClrValue; object localValue; if (propertyValues.TryGetValue(localProperty, out localValue)) { if (localValue != keyValue) { foreignKeys.Remove(foreignKey); foreignKey = null; break; } } } } } if (foreignKey == null) { AstoriaTestLog.FailAndThrow("Could not find an appropriate foreign key"); } relatedForeignKeys.Add(foreignKey); } for (int i = 0; i < foreignKey.Properties.Length; i++) { NodeProperty p = foreignKey.Properties[i]; if (p.Name == foreignProperty.Name) { propertyValues[currentProperty] = foreignKey.Values[i].ClrValue; } else if (p.ForeignKeys.Count() > 0) { string foreign = p.ForeignKeys.First().PrimaryKey.Properties.OfType <ResourceProperty>().First().Name; ResourceProperty localProperty; if (reverseForeignKeyMap.TryGetValue(foreign, out localProperty)) { propertyValues[localProperty] = foreignKey.Values[i].ClrValue; } } } } foreach (ResourceProperty property in resType.Key.Properties.OfType <ResourceProperty>()) { if (!propertyValues.ContainsKey(property)) { propertyValues[property] = (object)null; } } foreach (KeyValuePair <ResourceProperty, object> pair in propertyValues) { keyProperties.Add(new ResourceInstanceSimpleProperty(pair.Key.Facets, pair.Key.Name, pair.Value)); } ResourceInstanceKey resourceInstanceKey = new ResourceInstanceKey(container, resType, keyProperties.ToArray()); return(resourceInstanceKey); }
internal KeyedResourceInstance CreateRandomResource(ResourceContainer container, KeyExpressions existingKeys, bool populateNavProps) { KeyExpressions relatedForeignKeys = new KeyExpressions(); ResourceInstanceKey key = ResourceInstanceUtil.CreateUniqueKey(container, this, relatedForeignKeys, existingKeys); List <ResourceInstanceProperty> properties = new List <ResourceInstanceProperty>(); // populate the non-key, non-navigation properties // foreach (ResourceProperty p in this.Properties.OfType <ResourceProperty>().Where(rp => rp.IsNavigation == false && rp.PrimaryKey == null)) { if (p.Facets.IsIdentity) { continue; } ResourceInstanceProperty property = p.CreateRandomResourceInstanceProperty(); properties.Add(property); } if (populateNavProps) { // populate the navigation properties, but don't go by key, as some foreign keys MAY NOT HAVE ASSOCIATED NAVIGATION PROPERTIES // foreach (ResourceProperty p in this.Properties.OfType <ResourceProperty>().Where(rp => rp.IsNavigation)) { // find a key for this navigation property KeyExpression navPropKey = null; foreach (KeyExpression keyExp in relatedForeignKeys) { //if (p.Type.Equals(keyExp.ResourceType) // || p.Type is ResourceType && (p.Type as ResourceType).BaseTypes.Contains(keyExp.ResourceType)) if (p.OtherAssociationEnd.ResourceType.Equals(keyExp.ResourceType)) { navPropKey = keyExp; break; } } ResourceContainer associatedContainer = container.FindDefaultRelatedContainer(p); if (navPropKey == null) { if (p.OtherAssociationEnd.ResourceType.Key.Properties.OfType <ResourceProperty>() .Where(rp => rp.ForeignKeys.Any()) .Any(rp => rp.ForeignKeys.First().PrimaryKey.Properties.OfType <ResourceProperty>().First().ResourceType.Equals(this))) { // this association has a fk back to the current type, so it cannot be based on any existing entity AstoriaTestLog.WriteLineIgnore("Skipping nav prop '{0}.{1}' due to foreign key constraint on entity being created", this.Name, p.Name); continue; } else { navPropKey = associatedContainer.Workspace.GetRandomExistingKey(associatedContainer, p.OtherAssociationEnd.ResourceType); } } if (navPropKey != null) { if (p.OtherAssociationEnd.Multiplicity == Multiplicity.Many) { properties.Add(ResourceInstanceUtil.CreateCollectionInstanceProperty(new KeyExpressions(navPropKey), navPropKey.ResourceContainer, p)); } else { properties.Add(ResourceInstanceUtil.CreateRefInstanceProperty(navPropKey, navPropKey.ResourceContainer, p)); } } } } return(ResourceInstanceUtil.CreateKeyedResourceInstance(key.CreateKeyExpression(container, this), container, properties.ToArray())); }