} // GetOpenPropertyValues public object GetPropertyValue(object targetResource, DSP.ResourceProperty resourceProperty) { if (resourceProperty.Kind == DSP.ResourcePropertyKind.ResourceSetReference) { // there are 4 possibilites // 1) both the property and things in the list are strongly typed // 2) the property is strong, but the list is not // 3) the property is weak, but the things inside the list are strong // 4) neither is defined in clr terms // GetValue will automatically take care of #1 and #2, but we need to handle #3 here RowEntityType target = targetResource as RowEntityType; IEnumerable list = (IEnumerable)this.GetValue(targetResource, resourceProperty.Name); Type genericList = typeof(IEnumerable <>).MakeGenericType(resourceProperty.ResourceType.InstanceType); if (genericList.IsAssignableFrom(list.GetType())) { return(list); } MethodInfo castMethod = typeof(Enumerable).GetMethod("Cast", BindingFlags.Static | BindingFlags.Public); castMethod = castMethod.MakeGenericMethod(resourceProperty.ResourceType.InstanceType); return(castMethod.Invoke(null, new object[] { list })); } else { return(this.GetValue(targetResource, resourceProperty.Name)); } } // GetPropertyValue
} // SetReference internal void SetReference_Internal(object targetResource, string propertyName, object propertyValue, bool setBackReference) { RowEntityType targetEntity = (RowEntityType)targetResource; RowEntityType propertyEntity = (RowEntityType)propertyValue; object oldValue = null; if (!targetEntity.Properties.TryGetValue(propertyName, out oldValue)) { targetEntity.Properties.Add(propertyName, propertyEntity); } else { targetEntity.Properties[propertyName] = propertyEntity; } if (setBackReference) { if (propertyEntity == null) { propertyEntity = (RowEntityType)oldValue; } if (propertyEntity != null) { this.SetReverseNavigation(targetEntity, propertyEntity, propertyName, (propertyValue == null)); } } }
public object ResetResource(object resource) { if (resource is RowEntityType) { RowEntityType entityResource = resource as RowEntityType; DSP.ResourceType type = Types.Where(t => t.Namespace + "." + t.Name == entityResource.TypeName).FirstOrDefault(); foreach (DSP.ResourceProperty property in type.Properties) { if ((property.Kind & DSP.ResourcePropertyKind.Key) == 0 && (property.Kind & DSP.ResourcePropertyKind.ResourceReference) == 0 && (property.Kind & DSP.ResourcePropertyKind.ResourceSetReference) == 0) { entityResource.Properties.Remove(property.Name); } } // reset dynamic properties foreach (string key in entityResource.Properties.Keys.Except(type.Properties.Select(p => p.Name)).ToList()) { //the ToList is so we can modify the collection inside the loop entityResource.Properties.Remove(key); } return(entityResource); } else { return(new RowComplexType(((RowComplexType)resource).TypeName)); } } // ResetResource
public bool EqualKeys(RowEntityType o, RowEntityType o2) { string[] keys = GetKeys(o); string[] keys2 = GetKeys(o2); if (keys.Count() == keys2.Count()) { bool keysEqual = true; for (int i = 0; i < keys.Count(); i++) { if (!keys[i].Equals(keys2[i])) { keysEqual = false; break; } } if (keysEqual) { object[] oValues = GetPropertyValues(keys, o); object[] o2Values = GetPropertyValues(keys, o2); bool valuesEqual = true; for (int i = 0; i < oValues.Length; i++) { if (!oValues[i].Equals(o2Values[i])) { valuesEqual = false; break; } } return(valuesEqual); } } return(false); }
private string[] GetKeys(RowEntityType t) { List <string> keys = new List <string>(); string simpleTypeName = t.TypeName.Substring(t.TypeName.LastIndexOf('.') + 1); DSP.ResourceType resourceType = types.Where(rt => rt.Name.Equals(simpleTypeName)).FirstOrDefault(); keys.AddRange(resourceType.KeyProperties.OfType <DSP.ResourceProperty>().Select <DSP.ResourceProperty, string>(rp2 => rp2.Name)); return(keys.ToArray()); }
public static object[] GetPropertyValues(string[] propertyNames, RowEntityType o) { List <object> propertyValues = new List <object>(); foreach (string propertyName in propertyNames) { propertyValues.Add(o.Properties[propertyName]); } return(propertyValues.ToArray()); }
/// <summary> /// For the given association from source to target, perform the appropriate reversed action /// </summary> /// <param name="source">the source of the association to reverse</param> /// <param name="target">the target of the association to reverse</param> /// <param name="forwardPropertyName">the name of the property from source to target</param> /// <param name="remove">whether or not to remove the reversed association</param> private void SetReverseNavigation(RowEntityType source, RowEntityType target, string forwardPropertyName, bool remove) { DSP.ResourceType targetType; DSP.ResourceType sourceType = this.GetResourceType(source); if (target == null) { targetType = sourceType.Properties.Single(p => p.Name == forwardPropertyName).ResourceType; } else { targetType = this.GetResourceType(target); } DSP.ResourceProperty forwardProperty = sourceType.Properties.SingleOrDefault(p => p.Name == forwardPropertyName); if (forwardProperty != null && forwardProperty.CustomState != null) { // because sourceType could match targetType, we need to make sure we filter out the target property DSP.ResourceProperty reverseProperty = targetType.Properties .SingleOrDefault(p => p != forwardProperty && p.CustomState != null && (string)p.CustomState == (string)forwardProperty.CustomState); if (reverseProperty != null) { bool reference = (reverseProperty.Kind & DSP.ResourcePropertyKind.ResourceReference) != 0; if (remove) { if (reference) { this.SetReference_Internal(target, reverseProperty.Name, null, false); } else { this.RemoveReferenceFromCollection_Internal(target, reverseProperty.Name, source, false); } } else { if (reference) { this.SetReference_Internal(target, reverseProperty.Name, source, false); } else { this.AddReferenceToCollection_Internal(target, reverseProperty.Name, source, false); } } } } }
} //RemoveReferenceFromCollection internal void RemoveReferenceFromCollection_Internal(object sourceResource, string propertyName, object resourceToBeRemoved, bool removeBackReference) { RowEntityType sourceEntity = sourceResource as RowEntityType; RowEntityType removedEntity = resourceToBeRemoved as RowEntityType; IList collection = (IList)sourceEntity.Properties[propertyName]; collection.Remove(removedEntity); if (removeBackReference) { SetReverseNavigation(sourceEntity, removedEntity, propertyName, true); } }
} // ResolveResource public void SaveChanges() { if (this.pendingChanges == null) { return; } foreach (KeyValuePair <object, EntityState> pendingChange in this.pendingChanges) { RowEntityType entity = pendingChange.Key as RowEntityType; List <RowEntityType> resourceList = EntitySetDictionary[entity.EntitySet]; switch (pendingChange.Value) { case EntityState.Added: // Check to see if item already exists foreach (RowEntityType existingEntity in resourceList) { if (EqualKeys(existingEntity, entity)) { throw new DataServiceException(500, "An entity with the given key already exists"); } } resourceList.Add(entity); break; case EntityState.Deleted: resourceList.Remove(entity); break; default: throw new Exception("Unsupported State"); } } this.pendingChanges.Clear(); } // SaveChanges
} // AddReferenceToCollection internal void AddReferenceToCollection_Internal(object targetResource, string propertyName, object resourceToBeAdded, bool addBackReference) { RowEntityType targetEntity = (RowEntityType)targetResource; RowEntityType entityResourceToBeAdded = (RowEntityType)resourceToBeAdded; IDictionary <string, object> targetProperties = targetEntity.Properties; object propertyValue; // if this is the first item that is getting added if (!targetProperties.TryGetValue(propertyName, out propertyValue)) { targetProperties[propertyName] = new List <RowEntityType>() { entityResourceToBeAdded }; } else { // Check to see if item already exists List <RowEntityType> collection = (List <RowEntityType>)targetProperties[propertyName]; foreach (RowEntityType existingEntity in collection) { if (EqualKeys(existingEntity, entityResourceToBeAdded)) { return; } } collection.Add(entityResourceToBeAdded); } if (addBackReference) { SetReverseNavigation(targetEntity, entityResourceToBeAdded, propertyName, false); } }
public object CreateResource(string containerName, string fullTypeName) { object resource = null; DSP.ResourceType type = this.Types.FirstOrDefault(t => t.FullName == fullTypeName); if (type == null) { throw new DataServiceException((int)Net.HttpStatusCode.BadRequest, "No type of name '" + fullTypeName + "' exists"); } if (type.IsAbstract) { throw new DataServiceException((int)Net.HttpStatusCode.BadRequest, "Cannot create an instance of abstract type '" + fullTypeName + "'"); } if (containerName == null) { return(new RowComplexType(fullTypeName)); } else { DSP.ResourceSet container = containers.FirstOrDefault(rc => rc.Name == containerName); if (container == null) { throw new DataServiceException((int)Net.HttpStatusCode.BadRequest, "No container of name '" + containerName + "' exists"); } bool belongsInContainer = false; DSP.ResourceType typeForContainerCheck = type; while (typeForContainerCheck != null && !belongsInContainer) { if (typeForContainerCheck == container.ResourceType) { belongsInContainer = true; } else { typeForContainerCheck = typeForContainerCheck.BaseType; } } if (!belongsInContainer) { throw new DataServiceException((int)Net.HttpStatusCode.BadRequest, "An entity of type '" + fullTypeName + "' cannot be added to '" + containerName + "'"); } if (type.InstanceType == typeof(RowEntityType)) { resource = new RowEntityType(containerName, fullTypeName); } else { ConstructorInfo constructor = type.InstanceType.GetConstructor(new Type[] { typeof(string) }); if (constructor != null) { resource = constructor.Invoke(new object[] { containerName }); } else { constructor = type.InstanceType.GetConstructor(new Type[] { }); resource = constructor.Invoke(new object[] { }); } } foreach (DSP.ResourceProperty property in type.Properties.Where(p => p.Kind == DSP.ResourcePropertyKind.ResourceSetReference)) { this.SetValue(resource, property.Name, new List <RowEntityType>()); } foreach (DSP.ResourceProperty property in type.Properties.Where(p => ServerGeneratedCustomState.Equals(p.CustomState))) { if (property.ResourceType.InstanceType != typeof(int)) { throw new DataServiceException(500, "Auto incrementing is not supported for non-int properties"); } int value; if (!autoIncremementingProperties.TryGetValue(property.Name, out value)) { value = 0; } this.SetValue(resource, property.Name, value); autoIncremementingProperties[property.Name] = value + 1; } this.PendingChanges.Add(new KeyValuePair <object, EntityState>(resource, EntityState.Added)); return(resource); } } // CreateResource