internal static bool IsPropertyKeyProperty(PropertyInfo property, out ResourceKeyKind keyKind) { keyKind = ~ResourceKeyKind.AttributedKey; if (WebUtil.IsPrimitiveType(property.PropertyType) && !property.PropertyType.IsGenericType) { DataServiceKeyAttribute attribute = property.ReflectedType.GetCustomAttributes(true).OfType <DataServiceKeyAttribute>().FirstOrDefault <DataServiceKeyAttribute>(); if ((attribute != null) && attribute.KeyNames.Contains(property.Name)) { keyKind = ResourceKeyKind.AttributedKey; return(true); } if (property.Name == (property.DeclaringType.Name + "ID")) { keyKind = ResourceKeyKind.TypeNameId; return(true); } if (property.Name == "ID") { keyKind = ResourceKeyKind.Id; return(true); } } return(false); }
private static void BuildTypeProperties(ResourceType parentResourceType, IDictionary <Type, ResourceType> knownTypes, IDictionary <ResourceType, List <ResourceType> > childTypes, Queue <ResourceType> unvisitedTypes, IEnumerable <ResourceSet> entitySets) { BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance; if (parentResourceType.BaseType != null) { bindingFlags |= BindingFlags.DeclaredOnly; } HashSet <string> set = new HashSet <string>(IgnorePropertiesAttribute.GetProperties(parentResourceType.InstanceType, false, bindingFlags), StringComparer.Ordinal); HashSet <string> source = new HashSet <string>(LoadETagProperties(parentResourceType), StringComparer.Ordinal); ResourceKeyKind kind = (ResourceKeyKind)0x7fffffff; PropertyInfo[] properties = parentResourceType.InstanceType.GetProperties(bindingFlags); if (!properties.Any <PropertyInfo>() && (parentResourceType.BaseType == null)) { throw new NotSupportedException(System.Data.Services.Strings.ReflectionProvider_ResourceTypeHasNoPublicallyVisibleProperties(parentResourceType.FullName)); } foreach (PropertyInfo info in properties) { if (!set.Contains(info.Name)) { ResourceType collectionResourceType; if (!info.CanRead || (info.GetIndexParameters().Length != 0)) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_InvalidProperty(info.Name, parentResourceType.FullName)); } ResourcePropertyKind collection = (ResourcePropertyKind)(-1); Type propertyType = info.PropertyType; bool flag = false; if (!BaseServiceProvider.TryGetType(knownTypes, propertyType, out collectionResourceType)) { Type iEnumerableElement = BaseServiceProvider.GetIEnumerableElement(info.PropertyType); if (iEnumerableElement != null) { BaseServiceProvider.TryGetType(knownTypes, iEnumerableElement, out collectionResourceType); flag = true; propertyType = iEnumerableElement; } } if (collectionResourceType != null) { if (collectionResourceType.ResourceTypeKind == ResourceTypeKind.Primitive) { if (flag) { collection = ResourcePropertyKind.Collection; } else { ResourceKeyKind kind3; if (((parentResourceType.BaseType == null) && (parentResourceType.ResourceTypeKind == ResourceTypeKind.EntityType)) && IsPropertyKeyProperty(info, out kind3)) { if (kind3 < kind) { if (parentResourceType.KeyProperties.Count != 0) { parentResourceType.RemoveKeyProperties(); } kind = kind3; collection = ResourcePropertyKind.Key | ResourcePropertyKind.Primitive; } else if (kind3 == kind) { collection = ResourcePropertyKind.Key | ResourcePropertyKind.Primitive; } else { collection = ResourcePropertyKind.Primitive; } } else { collection = ResourcePropertyKind.Primitive; } } } else if (collectionResourceType.ResourceTypeKind == ResourceTypeKind.ComplexType) { collection = flag ? ResourcePropertyKind.Collection : ResourcePropertyKind.ComplexType; } else if (collectionResourceType.ResourceTypeKind == ResourceTypeKind.EntityType) { collection = flag ? ResourcePropertyKind.ResourceSetReference : ResourcePropertyKind.ResourceReference; } } else { collectionResourceType = IsEntityOrComplexType(propertyType, knownTypes, childTypes, unvisitedTypes); if (collectionResourceType != null) { if (collectionResourceType.ResourceTypeKind == ResourceTypeKind.ComplexType) { if (flag) { if (BaseServiceProvider.GetIEnumerableElement(propertyType) != null) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_CollectionOfCollectionProperty(info.Name, parentResourceType.FullName)); } collection = ResourcePropertyKind.Collection; } else { collection = ResourcePropertyKind.ComplexType; } } else { collection = flag ? ResourcePropertyKind.ResourceSetReference : ResourcePropertyKind.ResourceReference; } } } if ((collectionResourceType == null) || ((collectionResourceType.ResourceTypeKind == ResourceTypeKind.EntityType) && (parentResourceType.ResourceTypeKind == ResourceTypeKind.ComplexType))) { if (collectionResourceType != null) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_ComplexTypeWithNavigationProperty(info.Name, parentResourceType.FullName)); } if (flag && (BaseServiceProvider.GetIEnumerableElement(propertyType) != null)) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_CollectionOfCollectionProperty(info.Name, parentResourceType.FullName)); } if (flag) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_CollectionOfUnsupportedTypeProperty(info.Name, parentResourceType.FullName, propertyType)); } if (CommonUtil.IsUnsupportedType(propertyType)) { throw new InvalidOperationException(System.Data.Services.Strings.BadProvider_UnsupportedPropertyType(info.Name, parentResourceType.FullName)); } throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_InvalidProperty(info.Name, parentResourceType.FullName)); } if ((collectionResourceType.ResourceTypeKind == ResourceTypeKind.EntityType) && (InternalGetContainerForResourceType(propertyType, entitySets) == null)) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_EntityPropertyWithNoEntitySet(parentResourceType.FullName, info.Name)); } if (collection == ResourcePropertyKind.Collection) { collectionResourceType = ResourceType.GetCollectionResourceType(collectionResourceType); } if (source.Remove(info.Name)) { collection |= ResourcePropertyKind.ETag; } ResourceProperty property = new ResourceProperty(info.Name, collection, collectionResourceType); MimeTypeAttribute mimeTypeAttribute = MimeTypeAttribute.GetMimeTypeAttribute(info); if (mimeTypeAttribute != null) { property.MimeType = mimeTypeAttribute.MimeType; } parentResourceType.AddProperty(property); } } if ((parentResourceType.ResourceTypeKind == ResourceTypeKind.EntityType) && ((parentResourceType.KeyProperties == null) || (parentResourceType.KeyProperties.Count == 0))) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_KeyPropertiesCannotBeIgnored(parentResourceType.FullName)); } if (source.Count != 0) { throw new InvalidOperationException(System.Data.Services.Strings.ReflectionProvider_ETagPropertyNameNotValid(source.ElementAt <string>(0), parentResourceType.FullName)); } }
/// <summary>Checks whether the given property is a key property.</summary> /// <param name="property">property to check</param> /// <param name="keyKind">returns the key kind of the property, based on the heuristic it matches</param> /// <returns>true if this is a key property, else returns false</returns> internal static bool IsPropertyKeyProperty(PropertyInfo property, out ResourceKeyKind keyKind) { keyKind = (ResourceKeyKind)(-1); // Only primitive types are allowed to be keys. // Checks for generic to exclude Nullable<> value-type primitives, since we don't allows keys to be null. if (WebUtil.IsPrimitiveType(property.PropertyType) && !property.PropertyType.IsGenericType) { DataServiceKeyAttribute keyAttribute = property.ReflectedType.GetCustomAttributes(true).OfType<DataServiceKeyAttribute>().FirstOrDefault(); if (keyAttribute != null && keyAttribute.KeyNames.Contains(property.Name)) { keyKind = ResourceKeyKind.AttributedKey; return true; } // For now, the key property must be {TypeName}Id or Id and the property // type must be primitive, since we do not support non-primitive types // as keys if (property.Name == property.DeclaringType.Name + "ID") { keyKind = ResourceKeyKind.TypeNameId; return true; } else if (property.Name == "ID") { keyKind = ResourceKeyKind.Id; return true; } } return false; }
internal static bool IsPropertyKeyProperty(PropertyInfo property, out ResourceKeyKind keyKind) { keyKind = ~ResourceKeyKind.AttributedKey; if (WebUtil.IsPrimitiveType(property.PropertyType) && !property.PropertyType.IsGenericType) { DataServiceKeyAttribute attribute = property.ReflectedType.GetCustomAttributes(true).OfType<DataServiceKeyAttribute>().FirstOrDefault<DataServiceKeyAttribute>(); if ((attribute != null) && attribute.KeyNames.Contains(property.Name)) { keyKind = ResourceKeyKind.AttributedKey; return true; } if (property.Name == (property.DeclaringType.Name + "ID")) { keyKind = ResourceKeyKind.TypeNameId; return true; } if (property.Name == "ID") { keyKind = ResourceKeyKind.Id; return true; } } return false; }