public static EntityCollection <TElement> CreateCollection <T, TElement>(this T entity, Expression <Func <T, EntityCollection <TElement> > > expr, params TElement[] items) where T : EntityObject where TElement : EntityObject { if (expr.Body.NodeType != ExpressionType.MemberAccess) { throw new ArgumentException("Expression is not correct.", "expr"); } var member = ((MemberExpression)expr.Body).Member; PropertyInfo pi = member as PropertyInfo; if (pi == null) { throw new ArgumentException("Expression is not correct.", "expr"); } EdmRelationshipNavigationPropertyAttribute attribute = (EdmRelationshipNavigationPropertyAttribute)Attribute.GetCustomAttribute(pi, typeof(EdmRelationshipNavigationPropertyAttribute)); EntityCollection <TElement> result = new EntityCollection <TElement>(); RelationshipManager rm = RelationshipManager.Create(entity); rm.InitializeRelatedCollection(attribute.RelationshipName, attribute.TargetRoleName, result); foreach (var item in items) { result.Add(item); } return(result); }
private static object[] GetArgs(EdmRelationshipNavigationPropertyAttribute attribute) { return(new object[] { attribute.RelationshipNamespaceName, attribute.RelationshipName, attribute.TargetRoleName }); }
internal void ResolveNavigationProperty(StructuralType declaringType, PropertyInfo propertyInfo) { IEnumerable <EdmRelationshipNavigationPropertyAttribute> customAttributes = propertyInfo.GetCustomAttributes <EdmRelationshipNavigationPropertyAttribute>(false); EdmType edmType; if (!this.TryGetLoadedType(propertyInfo.PropertyType, out edmType) || edmType.BuiltInTypeKind != BuiltInTypeKind.EntityType && edmType.BuiltInTypeKind != BuiltInTypeKind.CollectionType) { this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.Validator_OSpace_InvalidNavPropReturnType((object)propertyInfo.Name, (object)propertyInfo.DeclaringType.FullName, (object)propertyInfo.PropertyType.FullName))); } else { EdmRelationshipNavigationPropertyAttribute propertyAttribute = customAttributes.First <EdmRelationshipNavigationPropertyAttribute>(); EdmMember member = (EdmMember)null; EdmType type; if (this.SessionData.TypesInLoading.TryGetValue(propertyAttribute.RelationshipNamespaceName + "." + propertyAttribute.RelationshipName, out type) && Helper.IsAssociationType(type)) { AssociationType associationType = (AssociationType)type; if (associationType != null) { NavigationProperty navigationProperty = new NavigationProperty(propertyInfo.Name, TypeUsage.Create(edmType)); navigationProperty.RelationshipType = (RelationshipType)associationType; member = (EdmMember)navigationProperty; if (associationType.Members[0].Name == propertyAttribute.TargetRoleName) { navigationProperty.ToEndMember = (RelationshipEndMember)associationType.Members[0]; navigationProperty.FromEndMember = (RelationshipEndMember)associationType.Members[1]; } else if (associationType.Members[1].Name == propertyAttribute.TargetRoleName) { navigationProperty.ToEndMember = (RelationshipEndMember)associationType.Members[1]; navigationProperty.FromEndMember = (RelationshipEndMember)associationType.Members[0]; } else { this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.TargetRoleNameInNavigationPropertyNotValid((object)propertyInfo.Name, (object)propertyInfo.DeclaringType.FullName, (object)propertyAttribute.TargetRoleName, (object)propertyAttribute.RelationshipName))); member = (EdmMember)null; } if (member != null && ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType != declaringType.ClrType) { this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.NavigationPropertyRelationshipEndTypeMismatch((object)declaringType.FullName, (object)navigationProperty.Name, (object)associationType.FullName, (object)navigationProperty.FromEndMember.Name, (object)((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType))); member = (EdmMember)null; } } } else { this.SessionData.EdmItemErrors.Add(new EdmItemError(Strings.RelationshipNameInNavigationPropertyNotValid((object)propertyInfo.Name, (object)propertyInfo.DeclaringType.FullName, (object)propertyAttribute.RelationshipName))); } if (member == null) { return; } declaringType.AddMember(member); } }
public static bool IsUnloadedEntityAssociation(object item, MemberInfo fieldOrProp) { Type propertyType = null; bool flag2; if (fieldOrProp is PropertyInfo) { propertyType = ((PropertyInfo)fieldOrProp).PropertyType; } else { if (!(fieldOrProp is FieldInfo)) { return(false); } propertyType = ((FieldInfo)fieldOrProp).FieldType; } EdmRelationshipNavigationPropertyAttribute attribute = (EdmRelationshipNavigationPropertyAttribute)fieldOrProp.GetCustomAttributes(typeof(EdmRelationshipNavigationPropertyAttribute), true).FirstOrDefault <object>(); if (attribute == null) { return(false); } IEntityWithRelationships relationships = item as IEntityWithRelationships; if (relationships == null) { return(true); } Type type2 = (flag2 = propertyType.IsGenericType && propertyType.Name.StartsWith("EntityCollection")) ? propertyType.GetGenericArguments()[0] : propertyType; string str = attribute.RelationshipNamespaceName + "." + attribute.RelationshipName; MethodInfo method = typeof(RelationshipManager).GetMethod(flag2 ? "GetRelatedCollection" : "GetRelatedReference", new Type[] { typeof(string), typeof(string) }); if (method == null) { return(true); } object obj2 = method.MakeGenericMethod(new Type[] { type2 }).Invoke(relationships.RelationshipManager, new object[] { str, attribute.TargetRoleName }); if (obj2 == null) { return(true); } Type type3 = flag2 ? typeof(EntityCollection <>) : typeof(EntityReference <>); PropertyInfo property = type3.MakeGenericType(new Type[] { type2 }).GetProperty("IsLoaded"); return((property == null) || !((bool)property.GetValue(obj2, null))); }
internal void ResolveNavigationProperty(StructuralType declaringType, PropertyInfo propertyInfo) { Debug.Assert(propertyInfo.IsDefined(typeof(EdmRelationshipNavigationPropertyAttribute), false), "The property must have navigation property defined"); // EdmScalarPropertyAttribute, EdmComplexPropertyAttribute and EdmRelationshipNavigationPropertyAttribute // are all EdmPropertyAttributes that we need to process. If the current property is not an EdmPropertyAttribute // we will just ignore it and skip to the next property. object[] relationshipPropertyAttributes = propertyInfo.GetCustomAttributes(typeof(EdmRelationshipNavigationPropertyAttribute), false); Debug.Assert(relationshipPropertyAttributes.Length == 1, "There should be exactly one property for every navigation property"); // The only valid return types from navigation properties are: // (1) EntityType // (2) CollectionType containing valid EntityType // If TryGetLoadedType returned false, it could mean that we couldn't validate any part of the type, or it could mean that it's a generic // where the main generic type was validated, but the generic type parameter was not. We can't tell the difference, so just fail // with the same error message in both cases. The user will have to figure out which part of the type is wrong. // We can't just rely on checking for a generic because it can lead to a scenario where we report that the type parameter is invalid // when really it's the main generic type. That is more confusing than reporting the full name and letting the user determine the problem. EdmType propertyType; if (!TryGetLoadedType(propertyInfo.PropertyType, out propertyType) || !(propertyType.BuiltInTypeKind == BuiltInTypeKind.EntityType || propertyType.BuiltInTypeKind == BuiltInTypeKind.CollectionType)) { // Once an error is detected the property does not need to be validated further, just add to the errors // collection and continue with the next property. The failure will cause an exception to be thrown later during validation of all of the types. SessionData.EdmItemErrors.Add(new EdmItemError(System.Data.Entity.Strings.Validator_OSpace_InvalidNavPropReturnType(propertyInfo.Name, propertyInfo.DeclaringType.FullName, propertyInfo.PropertyType.FullName), null)); return; } // else we have a valid EntityType or CollectionType that contains EntityType. ResolveNonSchemaType enforces that a collection type // must contain an EntityType, and if it doesn't, propertyType will be null here. If propertyType is EntityType or CollectionType we know it is valid // Expecting EdmRelationshipNavigationPropertyAttribute to have AllowMultiple=False, so only look at first element in the attribute array EdmRelationshipNavigationPropertyAttribute attribute = (EdmRelationshipNavigationPropertyAttribute)relationshipPropertyAttributes[0]; EdmMember member = null; EdmType type; if (SessionData.TypesInLoading.TryGetValue(attribute.RelationshipNamespaceName + "." + attribute.RelationshipName, out type) && Helper.IsAssociationType(type)) { AssociationType relationshipType = (AssociationType)type; if (relationshipType != null) { // The return value of this property has been verified, so create the property now NavigationProperty navigationProperty = new NavigationProperty(propertyInfo.Name, TypeUsage.Create(propertyType), propertyInfo); navigationProperty.RelationshipType = relationshipType; member = navigationProperty; if (relationshipType.Members[0].Name == attribute.TargetRoleName) { navigationProperty.ToEndMember = (RelationshipEndMember)relationshipType.Members[0]; navigationProperty.FromEndMember = (RelationshipEndMember)relationshipType.Members[1]; } else if (relationshipType.Members[1].Name == attribute.TargetRoleName) { navigationProperty.ToEndMember = (RelationshipEndMember)relationshipType.Members[1]; navigationProperty.FromEndMember = (RelationshipEndMember)relationshipType.Members[0]; } else { SessionData.EdmItemErrors.Add(new EdmItemError(System.Data.Entity.Strings.TargetRoleNameInNavigationPropertyNotValid( propertyInfo.Name, propertyInfo.DeclaringType.FullName, attribute.TargetRoleName, attribute.RelationshipName), navigationProperty)); member = null; } if (member != null && ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType != declaringType.ClrType) { SessionData.EdmItemErrors.Add(new EdmItemError(System.Data.Entity.Strings.NavigationPropertyRelationshipEndTypeMismatch( declaringType.FullName, navigationProperty.Name, relationshipType.FullName, navigationProperty.FromEndMember.Name, ((RefType)navigationProperty.FromEndMember.TypeUsage.EdmType).ElementType.ClrType), navigationProperty)); member = null; } } } else { SessionData.EdmItemErrors.Add(new EdmItemError(System.Data.Entity.Strings.RelationshipNameInNavigationPropertyNotValid( propertyInfo.Name, propertyInfo.DeclaringType.FullName, attribute.RelationshipName), declaringType)); } if (member != null) { declaringType.AddMember(member); } }