private NavigationPropertyConfiguration AddNavigationProperty(PropertyInfo navigationProperty, EdmMultiplicity multiplicity, bool containsTarget) { if (navigationProperty == null) { throw Error.ArgumentNull("navigationProperty"); } if (!navigationProperty.ReflectedType.IsAssignableFrom(this.ClrType)) { throw Error.Argument("navigationProperty", SRResources.PropertyDoesNotBelongToType, navigationProperty.Name, this.ClrType.FullName); } this.ValidatePropertyNotAlreadyDefinedInBaseTypes(navigationProperty); this.ValidatePropertyNotAlreadyDefinedInDerivedTypes(navigationProperty); PropertyConfiguration propertyConfig; NavigationPropertyConfiguration navigationPropertyConfig; if (this.ExplicitProperties.ContainsKey(navigationProperty)) { propertyConfig = this.ExplicitProperties[navigationProperty]; if (propertyConfig.Kind != PropertyKind.Navigation) { throw Error.Argument("navigationProperty", SRResources.MustBeNavigationProperty, navigationProperty.Name, this.ClrType.FullName); } navigationPropertyConfig = propertyConfig as NavigationPropertyConfiguration; if (navigationPropertyConfig.Multiplicity != multiplicity) { throw Error.Argument("navigationProperty", SRResources.MustHaveMatchingMultiplicity, navigationProperty.Name, multiplicity); } } else { navigationPropertyConfig = new NavigationPropertyConfiguration( navigationProperty, multiplicity, this); if (containsTarget) { navigationPropertyConfig = navigationPropertyConfig.Contained(); } this.ExplicitProperties[navigationProperty] = navigationPropertyConfig; // make sure the related type is configured this.ModelBuilder.AddEntityType(navigationPropertyConfig.RelatedClrType); } return(navigationPropertyConfig); }
private void VerifyBindingPath(NavigationPropertyConfiguration navigationConfiguration, IList <MemberInfo> bindingPath) { Contract.Assert(navigationConfiguration != null); Contract.Assert(bindingPath != null); PropertyInfo navigation = bindingPath.Last() as PropertyInfo; if (navigation == null || navigation != navigationConfiguration.PropertyInfo) { throw Error.Argument("navigationConfiguration", SRResources.NavigationPropertyBindingPathIsNotValid, bindingPath.ConvertBindingPath(), navigationConfiguration.Name); } bindingPath.Aggregate(this.EntityType.ClrType, VerifyBindingSegment); }
public NavigationPropertyConfiguration HasRequired <TTargetEntity>( Expression <Func <TStructuralType, TTargetEntity> > navigationPropertyExpression, Expression <Func <TStructuralType, TTargetEntity, bool> > referentialConstraintExpression) where TTargetEntity : class { NavigationPropertyConfiguration navigation = this.GetOrCreateNavigationProperty(navigationPropertyExpression, EdmMultiplicity.One); IDictionary <PropertyInfo, PropertyInfo> referentialConstraints = PropertyPairSelectorVisitor.GetSelectedProperty(referentialConstraintExpression); foreach (KeyValuePair <PropertyInfo, PropertyInfo> constraint in referentialConstraints) { navigation.HasConstraint(constraint); } return(navigation); }
private static void FindNavigationProperties(this ODataModelBuilder builder, StructuralTypeConfiguration configuration, IList <Tuple <StructuralTypeConfiguration, IList <MemberInfo>, NavigationPropertyConfiguration> > navs, Stack <MemberInfo> path) { Contract.Assert(builder != null); Contract.Assert(configuration != null); Contract.Assert(navs != null); Contract.Assert(path != null); foreach (var property in configuration.Properties) { path.Push(property.PropertyInfo); NavigationPropertyConfiguration nav = property as NavigationPropertyConfiguration; ComplexPropertyConfiguration complex = property as ComplexPropertyConfiguration; CollectionPropertyConfiguration collection = property as CollectionPropertyConfiguration; if (nav != null) { // how about the containment? IList <MemberInfo> bindingPath = path.Reverse().ToList(); navs.Add( new Tuple <StructuralTypeConfiguration, IList <MemberInfo>, NavigationPropertyConfiguration>(configuration, bindingPath, nav)); } else if (complex != null) { StructuralTypeConfiguration complexType = builder.GetTypeConfigurationOrNull(complex.RelatedClrType) as StructuralTypeConfiguration; builder.FindAllNavigationProperties(complexType, navs, path); } else if (collection != null) { IEdmTypeConfiguration edmType = builder.GetTypeConfigurationOrNull(collection.ElementType); if (edmType != null && edmType.Kind == EdmTypeKind.Complex) { StructuralTypeConfiguration complexType = (StructuralTypeConfiguration)edmType; builder.FindAllNavigationProperties(complexType, navs, path); } } path.Pop(); } }
/// <summary> /// Removes the binding for the given navigation property and the given binding path. /// </summary> /// <param name="navigationConfiguration">The navigation property.</param> /// <param name="bindingPath">The binding path.</param> public virtual void RemoveBinding(NavigationPropertyConfiguration navigationConfiguration, string bindingPath) { if (navigationConfiguration == null) { throw Error.ArgumentNull("navigationConfiguration"); } Dictionary <string, NavigationPropertyBindingConfiguration> navigationPropertyBindingMap; if (this._navigationPropertyBindings.TryGetValue(navigationConfiguration, out navigationPropertyBindingMap)) { navigationPropertyBindingMap.Remove(bindingPath); if (!navigationPropertyBindingMap.Any()) { this._navigationPropertyBindings.Remove(navigationConfiguration); } } }
/// <summary> /// Initializes a new instance of the <see cref="NavigationPropertyBindingConfiguration"/> class. /// </summary> /// <param name="navigationProperty">The navigation property for the binding.</param> /// <param name="navigationSource">The target navigation source of the binding.</param> /// <param name="path">The path of current binding.</param> public NavigationPropertyBindingConfiguration(NavigationPropertyConfiguration navigationProperty, NavigationSourceConfiguration navigationSource, IList <MemberInfo> path) { if (navigationProperty == null) { throw new ArgumentNullException("navigationProperty"); } if (navigationSource == null) { throw new ArgumentNullException("navigationSource"); } if (path == null) { throw new ArgumentNullException("path"); } this.NavigationProperty = navigationProperty; this.TargetNavigationSource = navigationSource; this.Path = path; }
public NavigationPropertyBindingConfiguration HasOptionalBinding<TTargetType>( Expression<Func<TStructuralType, TTargetType>> navigationExpression, string targetEntitySet) where TTargetType : class { if (navigationExpression == null) { throw Error.ArgumentNull("navigationExpression"); } if (String.IsNullOrEmpty(targetEntitySet)) { throw Error.ArgumentNullOrEmpty("targetEntitySet"); } NavigationPropertyConfiguration navigation = this._structuralType.HasOptional(navigationExpression); IList<MemberInfo> bindingPath = new List<MemberInfo>(this._bindingPath); bindingPath.Add(navigation.PropertyInfo); NavigationSourceConfiguration entitySet = this._modelBuilder.EntitySet<TTargetType>(targetEntitySet).Configuration; return this._navigationSource.AddBinding(navigation, entitySet, bindingPath); }
/// <summary> /// Binds the given navigation property to the target navigation source. /// </summary> /// <param name="navigationConfiguration">The navigation property.</param> /// <param name="targetNavigationSource">The target navigation source.</param> /// <returns>The <see cref="NavigationPropertyBindingConfiguration"/> so that it can be further configured.</returns> public virtual NavigationPropertyBindingConfiguration AddBinding(NavigationPropertyConfiguration navigationConfiguration, NavigationSourceConfiguration targetNavigationSource) { if (navigationConfiguration == null) { throw Error.ArgumentNull("navigationConfiguration"); } if (targetNavigationSource == null) { throw Error.ArgumentNull("targetNavigationSource"); } IList <MemberInfo> bindingPath = new List <MemberInfo> { navigationConfiguration.PropertyInfo }; if (navigationConfiguration.DeclaringType != this.EntityType) { bindingPath.Insert(0, navigationConfiguration.DeclaringType.ClrType); } return(this.AddBinding(navigationConfiguration, targetNavigationSource, bindingPath)); }
public NavigationPropertyBindingConfiguration HasManyBinding<TTargetType, TDerivedType>( Expression<Func<TDerivedType, IEnumerable<TTargetType>>> navigationExpression, string targetEntitySet) where TTargetType : class where TDerivedType : class, TStructuralType { if (navigationExpression == null) { throw Error.ArgumentNull("navigationExpression"); } if (String.IsNullOrEmpty(targetEntitySet)) { throw Error.ArgumentNullOrEmpty("targetEntitySet"); } StructuralTypeConfiguration<TDerivedType> derivedConfiguration; if (this._structuralType.Configuration.Kind == EdmTypeKind.Entity) { derivedConfiguration = this._modelBuilder.EntityType<TDerivedType>().DerivesFrom<TStructuralType>(); } else { derivedConfiguration = this._modelBuilder.ComplexType<TDerivedType>().DerivesFrom<TStructuralType>(); } NavigationPropertyConfiguration navigation = derivedConfiguration.HasMany(navigationExpression); IList<MemberInfo> bindingPath = new List<MemberInfo>(this._bindingPath); bindingPath.Add(typeof(TDerivedType)); bindingPath.Add(navigation.PropertyInfo); NavigationSourceConfiguration entitySet = this._modelBuilder.EntitySet<TTargetType>(targetEntitySet).Configuration; return this._navigationSource.AddBinding(navigation, entitySet, bindingPath); }
/// <summary> /// Finds the binding for the given navigation property and tries to create it if it does not exist. /// </summary> /// <param name="navigationConfiguration">The navigation property.</param> /// <param name="bindingPath">The binding path.</param> /// <returns>The <see cref="NavigationPropertyBindingConfiguration"/> so that it can be further configured.</returns> public virtual NavigationPropertyBindingConfiguration FindBinding(NavigationPropertyConfiguration navigationConfiguration, IList <MemberInfo> bindingPath) { if (navigationConfiguration == null) { throw Error.ArgumentNull("navigationConfiguration"); } if (bindingPath == null) { throw Error.ArgumentNullOrEmpty("bindingPath"); } string path = bindingPath.ConvertBindingPath(); Dictionary <string, NavigationPropertyBindingConfiguration> navigationPropertyBindings; if (this._navigationPropertyBindings.TryGetValue(navigationConfiguration, out navigationPropertyBindings)) { NavigationPropertyBindingConfiguration bindingConfiguration; if (navigationPropertyBindings.TryGetValue(path, out bindingConfiguration)) { return(bindingConfiguration); } } if (this._modelBuilder.BindingOptions == NavigationPropertyBindingOption.None) { return(null); } bool hasSingletonAttribute = navigationConfiguration.PropertyInfo.GetCustomAttributes <SingletonAttribute>().Any(); Type entityType = navigationConfiguration.RelatedClrType; NavigationSourceConfiguration[] matchedNavigationSources; if (hasSingletonAttribute) { matchedNavigationSources = this._modelBuilder.Singletons.Where(es => es.EntityType.ClrType == entityType).ToArray(); } else { matchedNavigationSources = this._modelBuilder.EntitySets.Where(es => es.EntityType.ClrType == entityType).ToArray(); } if (matchedNavigationSources.Length >= 1) { if (matchedNavigationSources.Length == 1 || this._modelBuilder.BindingOptions == NavigationPropertyBindingOption.Auto) { return(this.AddBinding(navigationConfiguration, matchedNavigationSources[0], bindingPath)); } throw Error.NotSupported( SRResources.CannotAutoCreateMultipleCandidates, path, navigationConfiguration.DeclaringType.FullName, this.Name, String.Join(", ", matchedNavigationSources.Select(s => s.Name))); } return(null); }
/// <summary> /// Finds the bindings <see cref="NavigationPropertyBindingConfiguration"/> for the given navigation property. /// </summary> /// <param name="navigationConfiguration">The navigation property.</param> /// <returns>The list of <see cref="NavigationPropertyBindingConfiguration"/> so that it can be further configured.</returns> public virtual IEnumerable <NavigationPropertyBindingConfiguration> FindBinding(NavigationPropertyConfiguration navigationConfiguration) { if (navigationConfiguration == null) { throw Error.ArgumentNull("navigationConfiguration"); } Dictionary <string, NavigationPropertyBindingConfiguration> navigationPropertyBindings; if (this._navigationPropertyBindings.TryGetValue(navigationConfiguration, out navigationPropertyBindings)) { return(navigationPropertyBindings.Values); } return(null); }
/// <summary> /// Initializes a new instance of the <see cref="NavigationPropertyBindingConfiguration"/> class. /// </summary> /// <param name="navigationProperty">The navigation property for the binding.</param> /// <param name="navigationSource">The target navigation source of the binding.</param> public NavigationPropertyBindingConfiguration(NavigationPropertyConfiguration navigationProperty, NavigationSourceConfiguration navigationSource) : this(navigationProperty, navigationSource, new MemberInfo[] { navigationProperty.PropertyInfo }) { }
/// <summary> /// Finds the <see cref="NavigationPropertyBindingConfiguration"/> for the given navigation property. /// </summary> /// <param name="navigationConfiguration">The navigation property.</param> /// <param name="bindingPath">The navigation binding path.</param> /// <returns>The binding if found.</returns> public NavigationPropertyBindingConfiguration FindBinding(NavigationPropertyConfiguration navigationConfiguration, IList <MemberInfo> bindingPath) { return(this._configuration.FindBinding(navigationConfiguration, bindingPath)); }
/// <summary> /// Finds the bindings <see cref="NavigationPropertyBindingConfiguration"/> for the given navigation property /// </summary> /// <param name="navigationConfiguration">The navigation property.</param> /// <returns>The bindings if found</returns> public IEnumerable <NavigationPropertyBindingConfiguration> FindBinding(NavigationPropertyConfiguration navigationConfiguration) { return(this._configuration.FindBinding(navigationConfiguration)); }