private void RegisterDetails()
        {
            foreach (Type dataObjectType in _metadata.Types)
            {
                DataObjectEdmTypeSettings typeSettings  = _metadata[dataObjectType];
                EdmEntityType             edmEntityType = _registeredEdmEntityTypes[dataObjectType];

                foreach (var detailProperty in typeSettings.DetailProperties)
                {
                    if (!_registeredEdmEntityTypes.ContainsKey(detailProperty.Value.DetailType))
                    {
                        throw new Exception($"Тип детейла {detailProperty.Value.DetailType.FullName} не найден для типа {dataObjectType.FullName}.");
                    }

                    EdmEntityType edmTargetEntityType = _registeredEdmEntityTypes[detailProperty.Value.DetailType];

                    var navigationProperty = new EdmNavigationPropertyInfo
                    {
                        Name               = GetEntityPropertName(detailProperty.Key),
                        Target             = edmTargetEntityType,
                        TargetMultiplicity = EdmMultiplicity.Many
                    };

                    EdmNavigationProperty unidirectionalNavigation = edmEntityType.AddUnidirectionalNavigation(navigationProperty);
                    this.SetAnnotationValue(unidirectionalNavigation, new ClrPropertyInfoAnnotation(detailProperty.Key));

                    EdmEntitySet thisEdmEntitySet   = _registeredEntitySets[dataObjectType];
                    EdmEntitySet targetEdmEntitySet = _registeredEntitySets[detailProperty.Value.DetailType];
                    thisEdmEntitySet.AddNavigationTarget(unidirectionalNavigation, targetEdmEntitySet);

                    // Add relation for all derived types.
                    if (_typeHierarchy.ContainsKey(dataObjectType))
                    {
                        foreach (Type derivedDataObjectType in _typeHierarchy[dataObjectType])
                        {
                            GetEdmEntitySet(derivedDataObjectType).AddNavigationTarget(unidirectionalNavigation, targetEdmEntitySet);
                        }
                    }
                }
            }
        }
        public void ValidateSerializationBlockingErrors()
        {
            EdmModel model = new EdmModel();

            EdmComplexType complexWithBadProperty = new EdmComplexType("Foo", "Bar");

            complexWithBadProperty.AddProperty(new EdmStructuralProperty(complexWithBadProperty, "baz", new EdmComplexTypeReference(new EdmComplexType("", ""), false)));
            model.AddElement(complexWithBadProperty);

            EdmEntityType          baseType = new EdmEntityType("Foo", "");
            IEdmStructuralProperty keyProp  = new EdmStructuralProperty(baseType, "Id", EdmCoreModel.Instance.GetInt32(false));

            baseType.AddProperty(keyProp);
            baseType.AddKeys(keyProp);

            EdmEntityType derivedType = new EdmEntityType("Foo", "Quip", baseType);

            model.AddElement(baseType);
            model.AddElement(derivedType);
            EdmNavigationProperty navProp = derivedType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
            {
                Name = "navProp", Target = derivedType, TargetMultiplicity = EdmMultiplicity.One
            });

            EdmEntityContainer container = new EdmEntityContainer("Foo", "Container");

            model.AddElement(container);
            container.AddElement(new EdmEntitySet(container, "badNameSet", baseType));

            StringBuilder          sb = new StringBuilder();
            IEnumerable <EdmError> errors;
            bool written        = model.TryWriteSchema(XmlWriter.Create(sb), out errors);
            var  expectedErrors = new EdmLibTestErrors()
            {
                { "([. Nullable=False])", EdmErrorCode.ReferencedTypeMustHaveValidName },
                { "(Foo.Quip)", EdmErrorCode.ReferencedTypeMustHaveValidName },
                { "(Microsoft.OData.Edm.EdmEntitySet)", EdmErrorCode.ReferencedTypeMustHaveValidName },
            };

            this.CompareErrors(errors, expectedErrors);
        }
 private IEnumerable <IEdmElement> GetEdmAnnotatables()
 {
     return(new IEdmElement[] {
         new EdmComplexType("", ""),
         new EdmEntityContainer("", ""),
         new EdmEntityType("", ""),
         new EdmEntitySet(new EdmEntityContainer("", ""), "", new EdmEntityType("", "")),
         EdmNavigationProperty.CreateNavigationPropertyWithPartner(
             new EdmNavigationPropertyInfo()
         {
             Name = "", Target = new EdmEntityType("", ""), TargetMultiplicity = EdmMultiplicity.One
         },
             new EdmNavigationPropertyInfo()
         {
             Name = "", Target = new EdmEntityType("", ""), TargetMultiplicity = EdmMultiplicity.One
         }),
         new EdmStructuredValue(null, Enumerable.Empty <IEdmPropertyValue>()),
         new EdmStringConstant(null, ""),
         new EdmStructuralProperty(new EdmComplexType("", ""), "", EdmCoreModel.Instance.GetBoolean(true)),
     });
 }
Exemple #4
0
        public void ParseComputeAsExpandQueryOption()
        {
            // Create model
            EdmModel         model         = new EdmModel();
            EdmEntityType    elementType   = model.AddEntityType("DevHarness", "Entity");
            EdmEntityType    targetType    = model.AddEntityType("DevHarness", "Navigation");
            EdmTypeReference typeReference = new EdmStringTypeReference(EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.String), false);

            targetType.AddProperty(new EdmStructuralProperty(targetType, "Prop1", typeReference));
            EdmNavigationPropertyInfo propertyInfo = new EdmNavigationPropertyInfo();

            propertyInfo.Name               = "Nav1";
            propertyInfo.Target             = targetType;
            propertyInfo.TargetMultiplicity = EdmMultiplicity.One;
            EdmProperty navigation = EdmNavigationProperty.CreateNavigationProperty(elementType, propertyInfo);

            elementType.AddProperty(navigation);

            EdmEntityContainer container = model.AddEntityContainer("Default", "Container");

            container.AddEntitySet("Entities", elementType);

            // Define queries and new up parser.
            Uri            root   = new Uri("http://host");
            Uri            url    = new Uri("http://host/Entities?$expand=Nav1($compute=cast(Prop1, 'Edm.String') as NavProperty1AsString)");
            ODataUriParser parser = new ODataUriParser(model, root, url);

            // parse and validate
            SelectExpandClause clause = parser.ParseSelectAndExpand();
            List <SelectItem>  items  = clause.SelectedItems.ToList();

            items.Count.Should().Be(1);
            ExpandedNavigationSelectItem expanded = items[0] as ExpandedNavigationSelectItem;
            List <ComputeExpression>     computes = expanded.ComputeOption.ComputedItems.ToList();

            computes.Count.Should().Be(1);
            computes[0].Alias.ShouldBeEquivalentTo("NavProperty1AsString");
            computes[0].Expression.ShouldBeSingleValueFunctionCallQueryNode();
            computes[0].Expression.TypeReference.ShouldBeEquivalentTo(typeReference);
        }
        public virtual IEdmModel GetEdmModel()
        {
            if (_edmModel != null)
            {
                return(_edmModel);
            }

            EdmModel           model     = new EdmModel();
            EdmEntityContainer container = new EdmEntityContainer("ns", "container");

            model.AddElement(container);

            EdmEntityType product = new EdmEntityType("ns", "Product");

            product.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            EdmStructuralProperty key = product.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32);

            product.AddKeys(key);
            model.AddElement(product);
            EdmEntitySet products = container.AddEntitySet("Products", product);

            EdmEntityType detailInfo = new EdmEntityType("ns", "DetailInfo");

            detailInfo.AddKeys(detailInfo.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            detailInfo.AddStructuralProperty("Title", EdmPrimitiveTypeKind.String);
            model.AddElement(detailInfo);
            EdmEntitySet detailInfos = container.AddEntitySet("DetailInfos", product);

            EdmNavigationProperty detailInfoNavProp = product.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "DetailInfo",
                TargetMultiplicity = EdmMultiplicity.One,
                Target             = detailInfo
            });

            products.AddNavigationTarget(detailInfoNavProp, detailInfos);
            _edmModel = model;
            return(_edmModel);
        }
Exemple #6
0
        public static IEdmModel GetEdmModel()
        {
            EdmModel model = new EdmModel();

            // Create and add product entity type.
            EdmEntityType product = new EdmEntityType("NS", "Product");

            product.AddKeys(product.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
            product.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            product.AddStructuralProperty("Price", EdmPrimitiveTypeKind.Double);
            model.AddElement(product);

            // Create and add category entity type.
            EdmEntityType category = new EdmEntityType("NS", "Category");

            category.AddKeys(category.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
            category.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            model.AddElement(category);

            // Set navigation from product to category.
            EdmNavigationPropertyInfo propertyInfo = new EdmNavigationPropertyInfo();

            propertyInfo.Name = "Category";
            propertyInfo.TargetMultiplicity = EdmMultiplicity.One;
            propertyInfo.Target             = category;
            EdmNavigationProperty productCategory = product.AddUnidirectionalNavigation(propertyInfo);

            // Create and add entity container.
            EdmEntityContainer container = new EdmEntityContainer("NS", "DefaultContainer");

            model.AddElement(container);

            // Create and add entity set for product and category.
            EdmEntitySet products   = container.AddEntitySet("Products", product);
            EdmEntitySet categories = container.AddEntitySet("Categories", category);

            products.AddNavigationTarget(productCategory, categories);

            return(model);
        }
Exemple #7
0
        public void Build(EntityTypeInfo typeInfo)
        {
            foreach ((PropertyInfo many, PropertyInfo join) in GetManyToManyInfo(_metadataProvider, typeInfo.ClrType))
            {
                if (many == null || many.DeclaringType != typeInfo.ClrType)
                {
                    continue;
                }

                IEdmNavigationProperty?joinNavigationProperty = GetJoinNavigationProperty(typeInfo, join.DeclaringType !);
                if (joinNavigationProperty == null)
                {
                    continue;
                }

                EntityTypeInfo principalInfo = _entityTypeInfos[join.PropertyType];
                EntityTypeInfo dependentInfo = _entityTypeInfos[many.DeclaringType];

                var edmDependentInfo = new EdmNavigationPropertyInfo()
                {
                    ContainsTarget      = true,
                    Name                = many.Name,
                    OnDelete            = EdmOnDeleteAction.None,
                    PrincipalProperties = principalInfo.EdmType.DeclaredKey,
                    Target              = principalInfo.EdmType,
                    TargetMultiplicity  = EdmMultiplicity.Many
                };
                IEdmNavigationProperty edmManyToManyProperty;
                if (typeInfo.ClrType.GetProperty(many.Name) == null)
                {
                    IEdmNavigationProperty edmNavigationProperty = EdmNavigationProperty.CreateNavigationProperty(dependentInfo.EdmType, edmDependentInfo);
                    edmManyToManyProperty = new OeEdmNavigationShadowProperty(edmNavigationProperty, many);
                    dependentInfo.EdmType.AddProperty(edmManyToManyProperty);
                }
                else
                {
                    edmManyToManyProperty = dependentInfo.EdmType.AddUnidirectionalNavigation(edmDependentInfo);
                }

                var targetNavigationProperty  = (IEdmNavigationProperty)_entityTypeInfos[join.DeclaringType !].EdmType.GetPropertyIgnoreCase(join.Name);
Exemple #8
0
        public void Build(EntityTypeInfo typeInfo)
        {
            (PropertyInfo Many, PropertyInfo Join)manyToManyInfo = GetManyToManyInfo(_metadataProvider, typeInfo.ClrType);
            if (manyToManyInfo.Many == null)
            {
                return;
            }

            IEdmNavigationProperty joinNavigationProperty = GetJoinNavigationProperty(typeInfo, manyToManyInfo.Join.DeclaringType);

            if (joinNavigationProperty == null)
            {
                return;
            }

            IEdmNavigationProperty targetNavigationProperty = GetTargetNavigationProperty(_entityTypeInfos[manyToManyInfo.Join.DeclaringType], manyToManyInfo.Join.PropertyType);

            if (targetNavigationProperty == null)
            {
                return;
            }

            EntityTypeInfo principalInfo    = _entityTypeInfos[manyToManyInfo.Join.PropertyType];
            EntityTypeInfo dependentInfo    = _entityTypeInfos[manyToManyInfo.Many.DeclaringType];
            var            edmDependentInfo = new EdmNavigationPropertyInfo()
            {
                ContainsTarget      = true,
                Name                = manyToManyInfo.Many.Name,
                OnDelete            = EdmOnDeleteAction.None,
                PrincipalProperties = principalInfo.EdmType.DeclaredKey,
                Target              = principalInfo.EdmType,
                TargetMultiplicity  = EdmMultiplicity.Many
            };
            EdmNavigationProperty edmManyToManyProperty = dependentInfo.EdmType.AddUnidirectionalNavigation(edmDependentInfo);

            var manyToManyJoinDescription = new ManyToManyJoinDescription(manyToManyInfo.Join.DeclaringType, joinNavigationProperty, targetNavigationProperty);

            _edmModel.SetAnnotationValue(edmManyToManyProperty, manyToManyJoinDescription);
        }
Exemple #9
0
        private IEdmProperty CreateEdmProperty(IEdmStructuredType declaringType, PropertyInfo propertyInfo)
        {
            IEdmProperty property;
            IEdmType     edmType    = this.GetOrCreateEdmTypeInternal(propertyInfo.PropertyType).EdmType;
            bool         isNullable = ClientTypeUtil.CanAssignNull(propertyInfo.PropertyType);

            if ((edmType.TypeKind == EdmTypeKind.Entity) || ((edmType.TypeKind == EdmTypeKind.Collection) && (((IEdmCollectionType)edmType).ElementType.TypeKind() == EdmTypeKind.Entity)))
            {
                IEdmEntityType type2 = declaringType as IEdmEntityType;
                if (type2 == null)
                {
                    throw System.Data.Services.Client.Error.InvalidOperation(System.Data.Services.Client.Strings.ClientTypeCache_NonEntityTypeCannotContainEntityProperties(propertyInfo.Name, propertyInfo.DeclaringType.ToString()));
                }
                property = EdmNavigationProperty.CreateNavigationPropertyWithPartner(propertyInfo.Name, edmType.ToEdmTypeReference(isNullable), null, false, EdmOnDeleteAction.None, "Partner", type2.ToEdmTypeReference(true), null, false, EdmOnDeleteAction.None);
            }
            else
            {
                property = new EdmStructuralProperty(declaringType, propertyInfo.Name, edmType.ToEdmTypeReference(isNullable));
            }
            property.SetClientPropertyAnnotation(new ClientPropertyAnnotation(property, propertyInfo, this.protocolVersion));
            return(property);
        }
Exemple #10
0
        public EdmParModel()
        {
            model  = new EdmModel();
            person = new EdmEntityType("NS", "Person");
            pet    = new EdmEntityType("NS", "Pet");
            model.AddElement(person);
            model.AddElement(pet);

            this.personNavPet = person.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
            {
                Name               = "NavPet",
                Target             = pet,
                TargetMultiplicity = EdmMultiplicity.Many,
            });

            this.personNavPetCon = person.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
            {
                Name               = "NavPetCon",
                Target             = pet,
                TargetMultiplicity = EdmMultiplicity.ZeroOrOne,
                ContainsTarget     = true,
            });

            this.personNavPetUnknown = person.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
            {
                Name               = "NavPetUnknown",
                Target             = pet,
                TargetMultiplicity = EdmMultiplicity.ZeroOrOne,
            });

            var container = new EdmEntityContainer("NS", "Con");

            model.AddElement(container);
            personSet = container.AddEntitySet("PersonSet", person);
            petSet    = container.AddEntitySet("PetSet", pet);

            personSet.AddNavigationTarget(this.personNavPet, petSet);
        }
        public void TestElementError()
        {
            var expectedErrors = new EdmLibTestErrors();

            this.ValidateElement(new EdmModel(), expectedErrors);
            this.ValidateElement(new EdmTerm("foo", "bar", EdmCoreModel.Instance.GetInt32(false)), expectedErrors);
            this.ValidateElement(new EdmEntityType("", ""), expectedErrors);
            this.ValidateElement(new EdmComplexType("", ""), expectedErrors);
            this.ValidateElement(new EdmFunction("foo", "bar", EdmCoreModel.Instance.GetStream(true)), expectedErrors);
            this.ValidateElement(new EdmFunctionImport(new EdmEntityContainer("", ""), "foo", new EdmFunction("namespace", "foo", EdmCoreModel.Instance.GetInt32(false))), expectedErrors);
            this.ValidateElement(new EdmEntityType("", "").AddStructuralProperty("foo", EdmCoreModel.Instance.GetString(true)), expectedErrors);
            this.ValidateElement(new EdmEntitySet(new EdmEntityContainer("", ""), "foo", new EdmEntityType("", "")), expectedErrors);
            this.ValidateElement(new EdmEnumType("", ""), expectedErrors);
            this.ValidateElement(EdmNavigationProperty.CreateNavigationPropertyWithPartner(
                                     new EdmNavigationPropertyInfo()
            {
                Name = "", Target = new EdmEntityType("", ""), TargetMultiplicity = EdmMultiplicity.One
            },
                                     new EdmNavigationPropertyInfo()
            {
                Name = "", Target = new EdmEntityType("", ""), TargetMultiplicity = EdmMultiplicity.One
            }), expectedErrors);
        }
        public void EdmNavigationPropertyPrincipalPropertiesShouldReturnPrincipalProperties()
        {
            EdmEntityType type   = new EdmEntityType("ns", "type");
            var           key    = type.AddStructuralProperty("Id1", EdmCoreModel.Instance.GetInt32(false));
            var           notKey = type.AddStructuralProperty("Id2", EdmCoreModel.Instance.GetString(false));
            var           p1     = type.AddStructuralProperty("p1", EdmCoreModel.Instance.GetInt32(false));
            var           p2     = type.AddStructuralProperty("p1", EdmCoreModel.Instance.GetString(false));

            type.AddKeys(key);

            var navInfo1 = new EdmNavigationPropertyInfo()
            {
                Name                = "nav",
                Target              = type,
                TargetMultiplicity  = EdmMultiplicity.Many,
                DependentProperties = new[] { p1, p2 },
                PrincipalProperties = new[] { key, notKey }
            };

            EdmNavigationProperty navProp = type.AddUnidirectionalNavigation(navInfo1);

            navProp.PrincipalProperties().Should().NotBeNull();
            navProp.PrincipalProperties().ShouldAllBeEquivalentTo(new[] { key, notKey });
        }
Exemple #13
0
        public CraftModel()
        {
            model = new EdmModel();

            var address = new EdmComplexType("NS", "Address");

            model.AddElement(address);

            var mail   = new EdmEntityType("NS", "Mail");
            var mailId = mail.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32);

            mail.AddKeys(mailId);
            model.AddElement(mail);

            var person = new EdmEntityType("NS", "Person");

            model.AddElement(person);
            var personId = person.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32);

            person.AddKeys(personId);

            person.AddStructuralProperty("Addr", new EdmComplexTypeReference(address, /*Nullable*/ false));
            MailBox = person.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
            {
                ContainsTarget     = true,
                Name               = "Mails",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = mail,
            });


            var container = new EdmEntityContainer("NS", "DefaultContainer");

            model.AddElement(container);
            MyLogin = container.AddSingleton("MyLogin", person);
        }
        /// <summary>
        /// Builds a context URI from the expected type annotation.
        /// </summary>
        /// <param name="payloadElementKind">The payload element kind to build the context URI for.</param>
        /// <param name="metadataDocumentUri">The metadata document URI.</param>
        /// <param name="expectedTypeAnnotation">The expected type annotation.</param>
        /// <returns>The constructed context URI.</returns>
        public static string BuildContextUri(ODataPayloadElementType payloadElementKind, string metadataDocumentUri, ExpectedTypeODataPayloadElementAnnotation expectedTypeAnnotation, string projectionString = null)
        {
            ExceptionUtilities.CheckArgumentNotNull(metadataDocumentUri, "metadataDocumentUri");
            ExceptionUtilities.CheckArgumentNotNull(expectedTypeAnnotation, "expectedTypeAnnotation");

            StringBuilder builder = new StringBuilder(metadataDocumentUri);

            switch (payloadElementKind)
            {
            // Entry payload
            case ODataPayloadElementType.EntityInstance:
            {
                EdmEntitySet entitySet = (EdmEntitySet)expectedTypeAnnotation.EdmEntitySet;
                ExceptionUtilities.Assert(entitySet != null, "Entity set is required for entry payloads.");

                builder.Append('#');
                AppendEntityContainerElement(builder, entitySet.Container, entitySet.Name);
                AppendTypeCastIfNeeded(builder, entitySet, expectedTypeAnnotation.EdmExpectedType.Definition);
                builder.Append(projectionString);
                builder.Append("/$entity");

                break;
            }

            // Feed payload
            case ODataPayloadElementType.EntitySetInstance:
            {
                EdmEntitySet entitySet = (EdmEntitySet)expectedTypeAnnotation.EdmEntitySet;
                ExceptionUtilities.Assert(entitySet != null, "Entity set is required for feed payloads.");
                builder.Append('#');
                AppendEntityContainerElement(builder, entitySet.Container, entitySet.Name);
                AppendTypeCastIfNeeded(builder, entitySet, expectedTypeAnnotation.EdmExpectedType.Definition);
                builder.Append(projectionString);

                break;
            }

            // Property payload
            case ODataPayloadElementType.PrimitiveProperty:                 // fall through
            case ODataPayloadElementType.PrimitiveMultiValueProperty:       // fall through
            case ODataPayloadElementType.ComplexMultiValueProperty:         // fall through
            case ODataPayloadElementType.ComplexProperty:                   // fall through
            case ODataPayloadElementType.NullPropertyInstance:
            // Collection payload
            case ODataPayloadElementType.EmptyCollectionProperty:       // fall through
            case ODataPayloadElementType.ComplexInstanceCollection:     // fall through
            case ODataPayloadElementType.PrimitiveCollection:
                builder.Append('#');

                // NOTE: property payloads can be produced by regular properties as well as function imports
                IEdmTypeReference edmExpectedType = null;
                if (expectedTypeAnnotation.EdmProperty != null)
                {
                    edmExpectedType = expectedTypeAnnotation.EdmProperty.Type;
                }
                else if (expectedTypeAnnotation.ProductFunctionImport != null)
                {
                    edmExpectedType = expectedTypeAnnotation.ProductFunctionImport.Operation.ReturnType;
                }
                else if (expectedTypeAnnotation.EdmExpectedType != null)
                {
                    edmExpectedType = expectedTypeAnnotation.EdmExpectedType;
                }

                if (edmExpectedType == null)
                {
                    if (expectedTypeAnnotation.EdmExpectedType != null)
                    {
                        AppendTypeName(builder, expectedTypeAnnotation.EdmExpectedType.Definition);
                    }
                    else if (expectedTypeAnnotation.ProductFunctionImport != null)
                    {
                        AppendTypeName(builder, expectedTypeAnnotation.ProductFunctionImport.Operation.ReturnType.Definition);
                    }
                }
                else
                {
                    AppendTypeName(builder, edmExpectedType.Definition);
                }

                break;

            // Entity reference link payload
            case ODataPayloadElementType.DeferredLink:
            case ODataPayloadElementType.LinkCollection:
            {
                IEdmEntitySet         entitySet          = expectedTypeAnnotation.EdmEntitySet;
                EdmNavigationProperty navigationProperty = expectedTypeAnnotation.EdmNavigationProperty as EdmNavigationProperty;
                IEdmEntityType        entityType         = navigationProperty.DeclaringEntityType;

                ExceptionUtilities.Assert(entitySet != null, "entitySet is required for entity reference link payloads.");
                ExceptionUtilities.Assert(navigationProperty != null, "Navigation property is required for entity reference link payloads.");

                builder.Append('#');

                if (payloadElementKind == ODataPayloadElementType.DeferredLink)
                {
                    builder.Append("$ref");
                }
                else if (payloadElementKind == ODataPayloadElementType.LinkCollection)
                {
                    builder.Append("Collection($ref)");
                }

                break;
            }

            // Service document payload
            case ODataPayloadElementType.ServiceDocumentInstance:       // fall through
            case ODataPayloadElementType.WorkspaceInstance:
                // NOTE: the builder already contains the metadata document URI.
                break;

            default:
                return(null);
            }

            return(builder.ToString());
        }
Exemple #15
0
        /// <summary>
        /// Построение объекта данных по сущности OData.
        /// </summary>
        /// <param name="edmEntity"> Сущность OData. </param>
        /// <param name="key"> Значение ключевого поля сущности. </param>
        /// <param name="dObjs"> Список объектов для обновления. </param>
        /// <param name="endObject"> Признак, что объект добавляется в конец списка обновления. </param>
        /// <returns> Объект данных. </returns>
        private DataObject GetDataObjectByEdmEntity(EdmEntityObject edmEntity, object key, List <DataObject> dObjs, bool endObject = false)
        {
            if (edmEntity == null)
            {
                return(null);
            }

            IEdmEntityType entityType = (IEdmEntityType)edmEntity.ActualEdmType;
            Type           objType    = _model.GetDataObjectType(_model.GetEdmEntitySet(entityType).Name);

            // Значение свойства.
            object value;

            // Получим значение ключа.
            var keyProperty = entityType.Properties().FirstOrDefault(prop => prop.Name == _model.KeyPropertyName);

            if (key != null)
            {
                value = key;
            }
            else
            {
                edmEntity.TryGetPropertyValue(keyProperty.Name, out value);
            }

            // Загрузим объект из хранилища, если он там есть (используем представление по умолчанию), или создадим, если нет, но только для POST.
            // Тем самым гарантируем загруженность свойств при необходимости обновления и установку нужного статуса.
            DataObject obj = ReturnDataObject(objType, value);

            // Добавляем объект в список для обновления, если там ещё нет объекта с таким ключом.
            var objInList = dObjs.FirstOrDefault(o => o.__PrimaryKey.ToString() == obj.__PrimaryKey.ToString());

            if (objInList == null)
            {
                if (!endObject)
                {
                    // Добавляем объект в начало списка.
                    dObjs.Insert(0, obj);
                }
                else
                {
                    // Добавляем в конец списка.
                    dObjs.Add(obj);
                }
            }

            // Все свойства объекта данных означим из пришедшей сущности, если они были там установлены(изменены).
            foreach (var prop in entityType.Properties())
            {
                string dataObjectPropName = _model.GetDataObjectProperty(entityType.FullTypeName(), prop.Name).Name;
                if (edmEntity.GetChangedPropertyNames().Contains(prop.Name))
                {
                    // Обработка мастеров и детейлов.
                    if (prop is EdmNavigationProperty)
                    {
                        EdmNavigationProperty navProp = (EdmNavigationProperty)prop;

                        edmEntity.TryGetPropertyValue(prop.Name, out value);

                        EdmMultiplicity edmMultiplicity = navProp.TargetMultiplicity();

                        // var aggregator = Information.GetAgregatePropertyName(objType);

                        // Обработка мастеров.
                        if (edmMultiplicity == EdmMultiplicity.One || edmMultiplicity == EdmMultiplicity.ZeroOrOne)
                        {
                            if (value != null && value is EdmEntityObject)
                            {
                                EdmEntityObject edmMaster = (EdmEntityObject)value;
                                DataObject      master    = GetDataObjectByEdmEntity(edmMaster, null, dObjs);

                                Information.SetPropValueByName(obj, dataObjectPropName, master);
                            }
                            else
                            {
                                Information.SetPropValueByName(obj, dataObjectPropName, null);
                            }
                        }

                        // Обработка детейлов.
                        if (edmMultiplicity == EdmMultiplicity.Many)
                        {
                            Type        detType = Information.GetPropertyType(objType, dataObjectPropName);
                            DetailArray detarr  = (DetailArray)Information.GetPropValueByName(obj, dataObjectPropName);

                            if (value != null && value is EdmEntityObjectCollection)
                            {
                                EdmEntityObjectCollection coll = (EdmEntityObjectCollection)value;
                                if (coll != null && coll.Count > 0)
                                {
                                    foreach (var edmEnt in coll)
                                    {
                                        DataObject det = GetDataObjectByEdmEntity(
                                            (EdmEntityObject)edmEnt,
                                            null,
                                            dObjs,
                                            true);

                                        if (det.__PrimaryKey == null)
                                        {
                                            detarr.AddObject(det);
                                        }
                                        else
                                        {
                                            detarr.SetByKey(det.__PrimaryKey, det);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                detarr.Clear();
                            }
                        }
                    }
                    else
                    {
                        // Обработка собственных свойств объекта (неключевых, т.к. ключ устанавливаем при начальной инициализации объекта obj).
                        if (prop.Name != keyProperty.Name)
                        {
                            Type dataObjectPropertyType = Information.GetPropertyType(objType, dataObjectPropName);
                            edmEntity.TryGetPropertyValue(prop.Name, out value);

                            // Если тип свойства относится к одному из зарегистрированных провайдеров файловых свойств,
                            // значит свойство файловое, и его нужно обработать особым образом.
                            if (FileController.HasDataObjectFileProvider(dataObjectPropertyType))
                            {
                                IDataObjectFileProvider dataObjectFileProvider = FileController.GetDataObjectFileProvider(dataObjectPropertyType);

                                // Обработка файловых свойств объектов данных.
                                string serializedFileDescription = value as string;
                                if (serializedFileDescription == null)
                                {
                                    // Файловое свойство было сброшено на клиенте.
                                    // Ассоциированный файл должен быть удален, после успешного сохранения изменений.
                                    // Для этого запоминаем метаданные ассоциированного файла, до того как свойство будет сброшено
                                    // (для получения метаданных свойство будет дочитано в объект данных).
                                    // Файловое свойство типа File хранит данные ассоциированного файла прямо в БД,
                                    // соответственно из файловой системы просто нечего удалять,
                                    // поэтому обходим его стороной, чтобы избежать лишных вычиток файлов из БД.
                                    if (dataObjectPropertyType != typeof(File))
                                    {
                                        _removingFileDescriptions.Add(dataObjectFileProvider.GetFileDescription(obj, dataObjectPropName));
                                    }

                                    // Сбрасываем файловое свойство в изменяемом объекте данных.
                                    Information.SetPropValueByName(obj, dataObjectPropName, null);
                                }
                                else
                                {
                                    // Файловое свойство было изменено, но не сброшено.
                                    // Если в метаданных файла присутствует FileUploadKey значит файл был загружен на сервер,
                                    // но еще не был ассоциирован с объектом данных, и это нужно сделать.
                                    FileDescription fileDescription = FileDescription.FromJson(serializedFileDescription);
                                    if (!(string.IsNullOrEmpty(fileDescription.FileUploadKey) || string.IsNullOrEmpty(fileDescription.FileName)))
                                    {
                                        Information.SetPropValueByName(obj, dataObjectPropName, dataObjectFileProvider.GetFileProperty(fileDescription));

                                        // Файловое свойство типа File хранит данные ассоциированного файла прямо в БД,
                                        // поэтому после успешного сохранения объекта данных, оссоциированный с ним файл должен быть удален из файловой системы.
                                        // Для этого запоминаем описание загруженного файла.
                                        if (dataObjectPropertyType == typeof(File))
                                        {
                                            _removingFileDescriptions.Add(fileDescription);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                // Преобразование типов для примитивных свойств.
                                if (value is DateTimeOffset)
                                {
                                    value = ((DateTimeOffset)value).UtcDateTime;
                                }
                                if (value is EdmEnumObject)
                                {
                                    value = ((EdmEnumObject)value).Value;
                                }

                                Information.SetPropValueByName(obj, dataObjectPropName, value);
                            }
                        }
                    }
                }
            }

            return(obj);
        }
Exemple #16
0
        public static IEdmModel GetEdmModel1()
        {
            EdmModel model = new EdmModel();

            // Complex Type
            EdmComplexType address = new EdmComplexType("WebApiDocNS", "Address");

            address.AddStructuralProperty("Country", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            model.AddElement(address);

            EdmComplexType subAddress = new EdmComplexType("WebApiDocNS", "SubAddress", address);

            subAddress.AddStructuralProperty("Street", EdmPrimitiveTypeKind.String);
            model.AddElement(subAddress);

            // Enum type
            EdmEnumType color = new EdmEnumType("WebApiDocNS", "Color");

            color.AddMember(new EdmEnumMember(color, "Red", new EdmEnumMemberValue(0)));
            color.AddMember(new EdmEnumMember(color, "Blue", new EdmEnumMemberValue(1)));
            color.AddMember(new EdmEnumMember(color, "Green", new EdmEnumMemberValue(2)));
            model.AddElement(color);

            // Entity type
            EdmEntityType customer = new EdmEntityType("WebApiDocNS", "Customer");

            customer.AddKeys(customer.AddStructuralProperty("CustomerId", EdmPrimitiveTypeKind.Int32));
            customer.AddStructuralProperty("Location", new EdmComplexTypeReference(address, isNullable: true));
            model.AddElement(customer);

            EdmEntityType vipCustomer = new EdmEntityType("WebApiDocNS", "VipCustomer", customer);

            vipCustomer.AddStructuralProperty("FavoriteColor", new EdmEnumTypeReference(color, isNullable: false));
            model.AddElement(vipCustomer);

            EdmEntityType order = new EdmEntityType("WebApiDocNS", "Order");

            order.AddKeys(order.AddStructuralProperty("OrderId", EdmPrimitiveTypeKind.Int32));
            order.AddStructuralProperty("Token", EdmPrimitiveTypeKind.Guid);
            model.AddElement(order);

            EdmEntityContainer container = new EdmEntityContainer("WebApiDocNS", "Container");
            EdmEntitySet       customers = container.AddEntitySet("Customers", customer);
            EdmEntitySet       orders    = container.AddEntitySet("Orders", order);

            model.AddElement(container);

            // EdmSingleton mary = container.AddSingleton("Mary", customer);

            // navigation properties
            EdmNavigationProperty ordersNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "Orders",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = order
            });

            customers.AddNavigationTarget(ordersNavProp, orders);

            // function
            IEdmTypeReference stringType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, isNullable: false);
            IEdmTypeReference intType    = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Int32, isNullable: false);

            EdmFunction getFirstName = new EdmFunction("WebApiDocNS", "GetFirstName", stringType, isBound: true, entitySetPathExpression: null, isComposable: false);

            getFirstName.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(getFirstName);

            EdmFunction getNumber = new EdmFunction("WebApiDocNS", "GetOrderCount", intType, isBound: false, entitySetPathExpression: null, isComposable: false);

            model.AddElement(getNumber);
            container.AddFunctionImport("GetOrderCount", getNumber);

            // action
            EdmAction calculate = new EdmAction("WebApiDocNS", "CalculateOrderPrice", returnType: null, isBound: true, entitySetPathExpression: null);

            calculate.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(calculate);

            EdmAction change = new EdmAction("WebApiDocNS", "ChangeCustomerById", returnType: null, isBound: false, entitySetPathExpression: null);

            change.AddParameter("Id", intType);
            model.AddElement(change);
            container.AddActionImport("ChangeCustomerById", change);

            return(model);
        }
Exemple #17
0
        public void ParseComputeAsLevel2ExpandQueryOption()
        {
            // Create model
            EdmModel      model         = new EdmModel();
            EdmEntityType elementType   = model.AddEntityType("DevHarness", "Entity");
            EdmEntityType targetType    = model.AddEntityType("DevHarness", "Navigation");
            EdmEntityType subTargetType = model.AddEntityType("DevHarness", "SubNavigation");

            EdmTypeReference typeReference = new EdmStringTypeReference(EdmCoreModel.Instance.GetPrimitiveType(EdmPrimitiveTypeKind.String), false);

            elementType.AddProperty(new EdmStructuralProperty(elementType, "Prop1", typeReference));
            targetType.AddProperty(new EdmStructuralProperty(targetType, "Prop1", typeReference));
            subTargetType.AddProperty(new EdmStructuralProperty(subTargetType, "Prop1", typeReference));

            EdmNavigationPropertyInfo propertyInfo = new EdmNavigationPropertyInfo();

            propertyInfo.Name               = "Nav1";
            propertyInfo.Target             = targetType;
            propertyInfo.TargetMultiplicity = EdmMultiplicity.One;
            EdmProperty navigation = EdmNavigationProperty.CreateNavigationProperty(elementType, propertyInfo);

            elementType.AddProperty(navigation);

            EdmNavigationPropertyInfo subPropertyInfo = new EdmNavigationPropertyInfo();

            subPropertyInfo.Name               = "SubNav1";
            subPropertyInfo.Target             = subTargetType;
            subPropertyInfo.TargetMultiplicity = EdmMultiplicity.One;
            EdmProperty subnavigation = EdmNavigationProperty.CreateNavigationProperty(targetType, subPropertyInfo);

            targetType.AddProperty(subnavigation);

            EdmEntityContainer container = model.AddEntityContainer("Default", "Container");

            container.AddEntitySet("Entities", elementType);

            // Define queries and new up parser.
            string address = "http://host/Entities?$compute=cast(Prop1, 'Edm.String') as Property1AsString, tolower(Prop1) as Property1Lower&" +
                             "$expand=Nav1($compute=cast(Prop1, 'Edm.String') as NavProperty1AsString;" +
                             "$expand=SubNav1($compute=cast(Prop1, 'Edm.String') as SubNavProperty1AsString))";
            Uri            root   = new Uri("http://host");
            Uri            url    = new Uri(address);
            ODataUriParser parser = new ODataUriParser(model, root, url);

            // parse
            ComputeClause      computeClause = parser.ParseCompute();
            SelectExpandClause selectClause  = parser.ParseSelectAndExpand();

            // validate top compute
            List <ComputeExpression> items = computeClause.ComputedItems.ToList();

            items.Count().Should().Be(2);
            items[0].Alias.ShouldBeEquivalentTo("Property1AsString");
            items[0].Expression.ShouldBeSingleValueFunctionCallQueryNode();
            items[0].Expression.TypeReference.ShouldBeEquivalentTo(typeReference);
            items[1].Alias.ShouldBeEquivalentTo("Property1Lower");
            items[1].Expression.ShouldBeSingleValueFunctionCallQueryNode();
            items[1].Expression.TypeReference.FullName().ShouldBeEquivalentTo("Edm.String");
            items[1].Expression.TypeReference.IsNullable.ShouldBeEquivalentTo(true); // tolower is built in function that allows nulls.

            // validate level 1 expand compute
            List <SelectItem> selectItems = selectClause.SelectedItems.ToList();

            selectItems.Count.Should().Be(1);
            ExpandedNavigationSelectItem expanded = selectItems[0] as ExpandedNavigationSelectItem;
            List <ComputeExpression>     computes = expanded.ComputeOption.ComputedItems.ToList();

            computes.Count.Should().Be(1);
            computes[0].Alias.ShouldBeEquivalentTo("NavProperty1AsString");
            computes[0].Expression.ShouldBeSingleValueFunctionCallQueryNode();
            computes[0].Expression.TypeReference.ShouldBeEquivalentTo(typeReference);

            // validate level 2 expand compute
            List <SelectItem> subSelectItems = expanded.SelectAndExpand.SelectedItems.ToList();

            subSelectItems.Count.Should().Be(1);
            ExpandedNavigationSelectItem subExpanded = subSelectItems[0] as ExpandedNavigationSelectItem;
            List <ComputeExpression>     subComputes = subExpanded.ComputeOption.ComputedItems.ToList();

            subComputes.Count.Should().Be(1);
            subComputes[0].Alias.ShouldBeEquivalentTo("SubNavProperty1AsString");
            subComputes[0].Expression.ShouldBeSingleValueFunctionCallQueryNode();
            subComputes[0].Expression.TypeReference.ShouldBeEquivalentTo(typeReference);
        }
Exemple #18
0
        public CustomersModelWithInheritance()
        {
            EdmModel model = new EdmModel();

            // Enum type simpleEnum
            EdmEnumType simpleEnum = new EdmEnumType("NS", "SimpleEnum");

            simpleEnum.AddMember(new EdmEnumMember(simpleEnum, "First", new EdmEnumMemberValue(0)));
            simpleEnum.AddMember(new EdmEnumMember(simpleEnum, "Second", new EdmEnumMemberValue(1)));
            simpleEnum.AddMember(new EdmEnumMember(simpleEnum, "Third", new EdmEnumMemberValue(2)));
            model.AddElement(simpleEnum);

            // complex type address
            EdmComplexType address = new EdmComplexType("NS", "Address");

            address.AddStructuralProperty("Street", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("State", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("ZipCode", EdmPrimitiveTypeKind.String);
            address.AddStructuralProperty("CountryOrRegion", EdmPrimitiveTypeKind.String);
            model.AddElement(address);

            // open complex type "Account"
            EdmComplexType account = new EdmComplexType("NS", "Account", null, false, true);

            account.AddStructuralProperty("Bank", EdmPrimitiveTypeKind.String);
            account.AddStructuralProperty("CardNum", EdmPrimitiveTypeKind.Int64);
            account.AddStructuralProperty("BankAddress", new EdmComplexTypeReference(address, isNullable: true));
            model.AddElement(account);

            EdmComplexType specialAccount = new EdmComplexType("NS", "SpecialAccount", account, false, true);

            specialAccount.AddStructuralProperty("SpecialCard", EdmPrimitiveTypeKind.String);
            model.AddElement(specialAccount);

            // entity type customer
            EdmEntityType customer = new EdmEntityType("NS", "Customer");

            customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            IEdmProperty customerName = customer.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);

            customer.AddStructuralProperty("SimpleEnum", simpleEnum.ToEdmTypeReference(isNullable: false));
            customer.AddStructuralProperty("Address", new EdmComplexTypeReference(address, isNullable: true));
            customer.AddStructuralProperty("Account", new EdmComplexTypeReference(account, isNullable: true));
            IEdmTypeReference primitiveTypeReference = EdmCoreModel.Instance.GetPrimitive(
                EdmPrimitiveTypeKind.String,
                isNullable: true);
            var city = customer.AddStructuralProperty(
                "City",
                primitiveTypeReference,
                defaultValue: null);

            model.AddElement(customer);

            // derived entity type special customer
            EdmEntityType specialCustomer = new EdmEntityType("NS", "SpecialCustomer", customer);

            specialCustomer.AddStructuralProperty("SpecialCustomerProperty", EdmPrimitiveTypeKind.Guid);
            specialCustomer.AddStructuralProperty("SpecialAddress", new EdmComplexTypeReference(address, isNullable: true));
            model.AddElement(specialCustomer);

            // entity type order (open entity type)
            EdmEntityType order = new EdmEntityType("NS", "Order", null, false, true);

            // EdmEntityType order = new EdmEntityType("NS", "Order");
            order.AddKeys(order.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            order.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            order.AddStructuralProperty("Amount", EdmPrimitiveTypeKind.Int32);
            model.AddElement(order);

            // derived entity type special order
            EdmEntityType specialOrder = new EdmEntityType("NS", "SpecialOrder", order, false, true);

            specialOrder.AddStructuralProperty("SpecialOrderProperty", EdmPrimitiveTypeKind.Guid);
            model.AddElement(specialOrder);

            // test entity
            EdmEntityType testEntity = new EdmEntityType("Microsoft.AspNet.OData.Test.Query.Expressions", "TestEntity");

            testEntity.AddStructuralProperty("SampleProperty", EdmPrimitiveTypeKind.Binary);
            model.AddElement(testEntity);

            // containment
            // my order
            EdmEntityType myOrder = new EdmEntityType("NS", "MyOrder");

            myOrder.AddKeys(myOrder.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            myOrder.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            model.AddElement(myOrder);

            // order line
            EdmEntityType orderLine = new EdmEntityType("NS", "OrderLine");

            orderLine.AddKeys(orderLine.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
            orderLine.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            model.AddElement(orderLine);

            EdmNavigationProperty orderLinesNavProp = myOrder.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "OrderLines",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = orderLine,
                ContainsTarget     = true,
            });

            EdmNavigationProperty nonContainedOrderLinesNavProp = myOrder.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "NonContainedOrderLines",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = orderLine,
                ContainsTarget     = false,
            });

            EdmAction tag = new EdmAction("NS", "tag", returnType: null, isBound: true, entitySetPathExpression: null);

            tag.AddParameter("entity", new EdmEntityTypeReference(orderLine, false));
            model.AddElement(tag);

            // entity sets
            EdmEntityContainer container = new EdmEntityContainer("NS", "ModelWithInheritance");

            model.AddElement(container);
            EdmEntitySet customers = container.AddEntitySet("Customers", customer);
            EdmEntitySet orders    = container.AddEntitySet("Orders", order);
            EdmEntitySet myOrders  = container.AddEntitySet("MyOrders", myOrder);

            // singletons
            EdmSingleton vipCustomer = container.AddSingleton("VipCustomer", customer);
            EdmSingleton mary        = container.AddSingleton("Mary", customer);
            EdmSingleton rootOrder   = container.AddSingleton("RootOrder", order);

            // annotations
            model.SetOptimisticConcurrencyAnnotation(customers, new[] { city });

            // containment
            IEdmContainedEntitySet orderLines = (IEdmContainedEntitySet)myOrders.FindNavigationTarget(orderLinesNavProp);

            // no-containment
            IEdmNavigationSource nonContainedOrderLines = myOrders.FindNavigationTarget(nonContainedOrderLinesNavProp);

            // actions
            EdmAction upgrade = new EdmAction("NS", "upgrade", returnType: null, isBound: true, entitySetPathExpression: null);

            upgrade.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(upgrade);

            EdmAction specialUpgrade =
                new EdmAction("NS", "specialUpgrade", returnType: null, isBound: true, entitySetPathExpression: null);

            specialUpgrade.AddParameter("entity", new EdmEntityTypeReference(specialCustomer, false));
            model.AddElement(specialUpgrade);

            // actions bound to collection
            EdmAction upgradeAll = new EdmAction("NS", "UpgradeAll", returnType: null, isBound: true, entitySetPathExpression: null);

            upgradeAll.AddParameter("entityset",
                                    new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(customer, false))));
            model.AddElement(upgradeAll);

            EdmAction upgradeSpecialAll = new EdmAction("NS", "UpgradeSpecialAll", returnType: null, isBound: true, entitySetPathExpression: null);

            upgradeSpecialAll.AddParameter("entityset",
                                           new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(specialCustomer, false))));
            model.AddElement(upgradeSpecialAll);

            // functions
            IEdmTypeReference returnType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Boolean, isNullable: false);
            IEdmTypeReference stringType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, isNullable: false);
            IEdmTypeReference intType    = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Int32, isNullable: false);

            EdmFunction IsUpgraded = new EdmFunction(
                "NS",
                "IsUpgraded",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            IsUpgraded.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(IsUpgraded);

            EdmFunction orderByCityAndAmount = new EdmFunction(
                "NS",
                "OrderByCityAndAmount",
                stringType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            orderByCityAndAmount.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            orderByCityAndAmount.AddParameter("city", stringType);
            orderByCityAndAmount.AddParameter("amount", intType);
            model.AddElement(orderByCityAndAmount);

            EdmFunction getOrders = new EdmFunction(
                "NS",
                "GetOrders",
                EdmCoreModel.GetCollection(order.ToEdmTypeReference(false)),
                isBound: true,
                entitySetPathExpression: null,
                isComposable: true);

            getOrders.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            getOrders.AddParameter("parameter", intType);
            model.AddElement(getOrders);

            EdmFunction IsSpecialUpgraded = new EdmFunction(
                "NS",
                "IsSpecialUpgraded",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            IsSpecialUpgraded.AddParameter("entity", new EdmEntityTypeReference(specialCustomer, false));
            model.AddElement(IsSpecialUpgraded);

            EdmFunction getSalary = new EdmFunction(
                "NS",
                "GetSalary",
                stringType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            getSalary.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(getSalary);

            getSalary = new EdmFunction(
                "NS",
                "GetSalary",
                stringType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            getSalary.AddParameter("entity", new EdmEntityTypeReference(specialCustomer, false));
            model.AddElement(getSalary);

            EdmFunction IsAnyUpgraded = new EdmFunction(
                "NS",
                "IsAnyUpgraded",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);
            EdmCollectionType edmCollectionType = new EdmCollectionType(new EdmEntityTypeReference(customer, false));

            IsAnyUpgraded.AddParameter("entityset", new EdmCollectionTypeReference(edmCollectionType));
            model.AddElement(IsAnyUpgraded);

            EdmFunction isCustomerUpgradedWithParam = new EdmFunction(
                "NS",
                "IsUpgradedWithParam",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            isCustomerUpgradedWithParam.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            isCustomerUpgradedWithParam.AddParameter("city", EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.String, isNullable: false));
            model.AddElement(isCustomerUpgradedWithParam);

            EdmFunction isCustomerLocal = new EdmFunction(
                "NS",
                "IsLocal",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            isCustomerLocal.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            model.AddElement(isCustomerLocal);

            EdmFunction entityFunction = new EdmFunction(
                "NS",
                "GetCustomer",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: false);

            entityFunction.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            entityFunction.AddParameter("customer", new EdmEntityTypeReference(customer, false));
            model.AddElement(entityFunction);

            EdmFunction getOrder = new EdmFunction(
                "NS",
                "GetOrder",
                order.ToEdmTypeReference(false),
                isBound: true,
                entitySetPathExpression: null,
                isComposable: true); // Composable

            getOrder.AddParameter("entity", new EdmEntityTypeReference(customer, false));
            getOrder.AddParameter("orderId", intType);
            model.AddElement(getOrder);

            // functions bound to collection
            EdmFunction isAllUpgraded = new EdmFunction("NS", "IsAllUpgraded", returnType, isBound: true,
                                                        entitySetPathExpression: null, isComposable: false);

            isAllUpgraded.AddParameter("entityset",
                                       new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(customer, false))));
            isAllUpgraded.AddParameter("param", intType);
            model.AddElement(isAllUpgraded);

            EdmFunction isSpecialAllUpgraded = new EdmFunction("NS", "IsSpecialAllUpgraded", returnType, isBound: true,
                                                               entitySetPathExpression: null, isComposable: false);

            isSpecialAllUpgraded.AddParameter("entityset",
                                              new EdmCollectionTypeReference(new EdmCollectionType(new EdmEntityTypeReference(specialCustomer, false))));
            isSpecialAllUpgraded.AddParameter("param", intType);
            model.AddElement(isSpecialAllUpgraded);

            // navigation properties
            EdmNavigationProperty ordersNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "Orders",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = order
            });

            mary.AddNavigationTarget(ordersNavProp, orders);
            vipCustomer.AddNavigationTarget(ordersNavProp, orders);
            customers.AddNavigationTarget(ordersNavProp, orders);
            orders.AddNavigationTarget(
                order.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name = "Customer",
                TargetMultiplicity = EdmMultiplicity.ZeroOrOne,
                Target             = customer
            }),
                customers);

            // navigation properties on derived types.
            EdmNavigationProperty specialOrdersNavProp = specialCustomer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "SpecialOrders",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = order
            });

            vipCustomer.AddNavigationTarget(specialOrdersNavProp, orders);
            customers.AddNavigationTarget(specialOrdersNavProp, orders);
            orders.AddNavigationTarget(
                specialOrder.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name = "SpecialCustomer",
                TargetMultiplicity = EdmMultiplicity.ZeroOrOne,
                Target             = customer
            }),
                customers);
            model.SetAnnotationValue <BindableOperationFinder>(model, new BindableOperationFinder(model));

            // set properties
            Model                     = model;
            Container                 = container;
            Customer                  = customer;
            Order                     = order;
            Address                   = address;
            Account                   = account;
            SpecialCustomer           = specialCustomer;
            SpecialOrder              = specialOrder;
            Orders                    = orders;
            Customers                 = customers;
            VipCustomer               = vipCustomer;
            Mary                      = mary;
            RootOrder                 = rootOrder;
            OrderLine                 = orderLine;
            OrderLines                = orderLines;
            NonContainedOrderLines    = nonContainedOrderLines;
            UpgradeCustomer           = upgrade;
            UpgradeSpecialCustomer    = specialUpgrade;
            CustomerName              = customerName;
            IsCustomerUpgraded        = isCustomerUpgradedWithParam;
            IsSpecialCustomerUpgraded = IsSpecialUpgraded;
            Tag = tag;
        }
Exemple #19
0
        /// <summary>
        /// Creates an Edm property.
        /// </summary>
        /// <param name="declaringType">Type declaring this property.</param>
        /// <param name="propertyInfo">PropertyInfo instance for this property.</param>
        /// <returns>Returns a new instance of Edm property.</returns>
        private IEdmProperty CreateEdmProperty(IEdmStructuredType declaringType, PropertyInfo propertyInfo)
        {
            IEdmType propertyEdmType = this.GetOrCreateEdmTypeInternal(propertyInfo.PropertyType).EdmType;

            Debug.Assert(
                propertyEdmType.TypeKind == EdmTypeKind.Entity ||
                propertyEdmType.TypeKind == EdmTypeKind.Complex ||
                propertyEdmType.TypeKind == EdmTypeKind.Primitive ||
                propertyEdmType.TypeKind == EdmTypeKind.Collection,
                "Property kind should be Entity, Complex, Primitive or Collection.");

            IEdmProperty edmProperty;
            bool         isPropertyNullable = ClientTypeUtil.CanAssignNull(propertyInfo.PropertyType);

            if (propertyEdmType.TypeKind == EdmTypeKind.Entity || (propertyEdmType.TypeKind == EdmTypeKind.Collection && ((IEdmCollectionType)propertyEdmType).ElementType.TypeKind() == EdmTypeKind.Entity))
            {
                IEdmEntityType declaringEntityType = declaringType as IEdmEntityType;
                if (declaringEntityType == null)
                {
                    throw c.Error.InvalidOperation(c.Strings.ClientTypeCache_NonEntityTypeCannotContainEntityProperties(propertyInfo.Name, propertyInfo.DeclaringType.ToString()));
                }

                // Create a navigation property representing one side of an association.
                // The partner representing the other side exists only inside this property and is not added to the target entity type,
                // so it should not cause any name collisions.
                edmProperty = EdmNavigationProperty.CreateNavigationPropertyWithPartner(
                    propertyInfo.Name,
                    propertyEdmType.ToEdmTypeReference(isPropertyNullable),
                    /*dependentProperties*/ null,
                    /*containsTarget*/ false,
                    EdmOnDeleteAction.None,
                    "Partner",
                    declaringEntityType.ToEdmTypeReference(true),
                    /*partnerDependentProperties*/ null,
                    /*partnerContainsTarget*/ false,
                    EdmOnDeleteAction.None);
            }
            else
            {
                edmProperty = new EdmStructuralProperty(declaringType, propertyInfo.Name, propertyEdmType.ToEdmTypeReference(isPropertyNullable));
            }

            FieldInfo backingField = null;

            if (this.ResolveBackingField != null)
            {
                // We only do this for "collections of entities" OR "complex properties"
                if (propertyEdmType.TypeKind == EdmTypeKind.Collection && !propertyEdmType.IsPrimitive() || propertyEdmType.TypeKind == EdmTypeKind.Complex)
                {
                    backingField = this.ResolveBackingField(propertyInfo);
                }

                if (backingField != null && backingField.FieldType != propertyInfo.PropertyType)
                {
                    backingField = null; // We disregard returned FieldInfo that has the wrong type.
                }
            }

            edmProperty.SetClientPropertyAnnotation(new ClientPropertyAnnotation(edmProperty, propertyInfo, backingField, this));
            return(edmProperty);
        }
Exemple #20
0
        private IEdmModel GetModel()
        {
            EdmModel myModel = new EdmModel();

            EdmComplexType shippingAddress = new EdmComplexType("MyNS", "ShippingAddress");

            shippingAddress.AddStructuralProperty("Street", EdmPrimitiveTypeKind.String);
            shippingAddress.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            shippingAddress.AddStructuralProperty("Region", EdmPrimitiveTypeKind.String);
            shippingAddress.AddStructuralProperty("PostalCode", EdmPrimitiveTypeKind.String);
            myModel.AddElement(shippingAddress);

            EdmComplexTypeReference shippingAddressReference = new EdmComplexTypeReference(shippingAddress, true);

            EdmEntityType order = new EdmEntityType("MyNS", "Order");

            order.AddKeys(order.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
            order.AddStructuralProperty("ShippingAddress", shippingAddressReference);
            myModel.AddElement(order);

            EdmEntityType person = new EdmEntityType("MyNS", "Person");

            myModel.AddElement(person);

            customer = new EdmEntityType("MyNS", "Customer");
            customer.AddKeys(customer.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
            customer.AddStructuralProperty("ContactName", EdmPrimitiveTypeKind.String);
            EdmNavigationPropertyInfo orderLinks = new EdmNavigationPropertyInfo
            {
                Name               = "Orders",
                Target             = order,
                TargetMultiplicity = EdmMultiplicity.Many
            };
            EdmNavigationPropertyInfo personLinks = new EdmNavigationPropertyInfo
            {
                Name               = "Parent",
                Target             = person,
                TargetMultiplicity = EdmMultiplicity.Many
            };

            customer.AddUnidirectionalNavigation(orderLinks);
            customer.AddUnidirectionalNavigation(personLinks);
            myModel.AddElement(customer);

            EdmEntityType product = new EdmEntityType("MyNS", "Product");

            product.AddKeys(product.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
            product.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            myModel.AddElement(product);

            EdmEntityType productDetail = new EdmEntityType("MyNS", "ProductDetail");

            productDetail.AddKeys(productDetail.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
            productDetail.AddStructuralProperty("Detail", EdmPrimitiveTypeKind.String);
            myModel.AddElement(productDetail);

            product.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "Details",
                Target             = productDetail,
                TargetMultiplicity = EdmMultiplicity.Many,
                ContainsTarget     = true,
            });

            EdmNavigationProperty favouriteProducts = customer.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "FavouriteProducts",
                Target             = product,
                TargetMultiplicity = EdmMultiplicity.Many,
            });
            EdmNavigationProperty productBeingViewed = customer.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "ProductBeingViewed",
                Target             = product,
                TargetMultiplicity = EdmMultiplicity.ZeroOrOne,
            });

            EdmEntityContainer container = new EdmEntityContainer("MyNS", "Example30");

            customers = container.AddEntitySet("Customers", customer);
            container.AddEntitySet("Orders", order);
            EdmEntitySet products = container.AddEntitySet("Products", product);

            customers.AddNavigationTarget(favouriteProducts, products);
            customers.AddNavigationTarget(productBeingViewed, products);

            myModel.AddElement(container);

            return(myModel);
        }
        private static IEdmModel GetEdmModel()
        {
            EdmModel model = new EdmModel();

            // Order
            EdmEntityType order = new EdmEntityType("NS", "Order", null, false, true);

            order.AddKeys(order.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));

            // Customer
            EdmEntityType customer = new EdmEntityType("NS", "Customer");

            customer.AddKeys(customer.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
            customer.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            model.AddElement(customer);

            // VipCustomer
            EdmEntityType vipCustomer = new EdmEntityType("NS", "VipCustomer", customer);

            model.AddElement(vipCustomer);

            EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
            EdmEntitySet       orders    = container.AddEntitySet("Orders", order);
            EdmEntitySet       customers = container.AddEntitySet("Customers", customer);
            EdmSingleton       me        = container.AddSingleton("Me", customer);

            model.AddElement(container);

            EdmNavigationProperty ordersNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "Orders",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = order
            });

            customers.AddNavigationTarget(ordersNavProp, orders);
            me.AddNavigationTarget(ordersNavProp, orders);

            EdmNavigationProperty orderNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "Order",
                TargetMultiplicity = EdmMultiplicity.One,
                Target             = order
            });

            customers.AddNavigationTarget(orderNavProp, orders);
            me.AddNavigationTarget(orderNavProp, orders);

            EdmNavigationProperty subOrdersNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "SubOrders",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = order
            });

            customers.AddNavigationTarget(subOrdersNavProp, orders, new EdmPathExpression("NS.VipCustomer/SubOrders"));
            me.AddNavigationTarget(subOrdersNavProp, orders, new EdmPathExpression("NS.VipCustomer/SubOrders"));


            EdmNavigationProperty subOrderNavProp = customer.AddUnidirectionalNavigation(
                new EdmNavigationPropertyInfo
            {
                Name = "SubOrder",
                TargetMultiplicity = EdmMultiplicity.Many,
                Target             = order
            });

            customers.AddNavigationTarget(subOrderNavProp, orders, new EdmPathExpression("NS.VipCustomer/SubOrder"));
            me.AddNavigationTarget(subOrderNavProp, orders, new EdmPathExpression("NS.VipCustomer/SubOrder"));

            return(model);
        }
 protected override void VisitEdmNavigationProperty(EdmNavigationProperty item)
 {
     _schemaWriter.WriteNavigationPropertyElementHeader(item);
     base.VisitEdmNavigationProperty(item);
     _schemaWriter.WriteEndElement();
 }
 internal void WriteNavigationPropertyElementHeader(EdmNavigationProperty member)
 {
     _xmlWriter.WriteStartElement(CsdlConstants.Element_NavigationProperty);
     _xmlWriter.WriteAttributeString(CsdlConstants.Attribute_Name, member.Name);
     _xmlWriter.WriteAttributeString(
         CsdlConstants.Attribute_Relationship,
         GetQualifiedTypeName(CsdlConstants.Value_Self, member.Association.Name));
     _xmlWriter.WriteAttributeString(CsdlConstants.Attribute_FromRole, member.GetFromEnd().Name);
     _xmlWriter.WriteAttributeString(CsdlConstants.Attribute_ToRole, member.ResultEnd.Name);
 }
 protected virtual void VisitEdmNavigationProperty(EdmNavigationProperty item)
 {
     VisitEdmNamedMetadataItem(item);
 }