Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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();
            }
        }
Exemple #5
0
        /// <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);
        }
Exemple #8
0
        /// <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);
        }
Exemple #10
0
        /// <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);
        }
Exemple #11
0
        /// <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));
 }