private static void BuildCompanies(IEdmModel model)
        {
            IEdmEntityType companyType = model.SchemaElements.OfType <IEdmEntityType>().First(e => e.Name == "Company");

            IList <IEdmComplexObject> addresses = BuildAddrsses(model);

            IEdmEntityObject[] untypedCompanies = new IEdmEntityObject[5];
            for (int i = 0; i < 5; i++)
            {
                dynamic untypedCompany = new EdmEntityObject(companyType);
                untypedCompany.ID       = i;
                untypedCompany.Location = addresses[i];
                untypedCompanies[i]     = untypedCompany;
            }

            IEdmCollectionTypeReference entityCollectionType =
                new EdmCollectionTypeReference(
                    new EdmCollectionType(
                        new EdmEntityTypeReference(companyType, isNullable: false)));

            Companies = new EdmEntityObjectCollection(entityCollectionType, untypedCompanies.ToList());
        }
Esempio n. 2
0
 private void AddAggregationPropertyValuesToModel(Dictionary <string, object> targetQueryableDictionary
                                                  , EdmEntityObject obj
                                                  , IEnumerable <Dictionary <string, object> > group
                                                  , EdmComplexType edmComplexType
                                                  , Dictionary <string, AggregateExpression> aggregatePropList)
 {
     foreach (var property in aggregatePropList)
     {
         var val           = aggregatePropList[property.Key];
         var primitiveKind = val.Expression.TypeReference.PrimitiveKind();
         if (val.Method != AggregationMethod.Custom)
         {
             var sourcePropertyName = val.Method != AggregationMethod.VirtualPropertyCount ?
                                      ((SingleValuePropertyAccessNode)val.Expression).Property.Name : null;
             var value = GetAggregatedValue(sourcePropertyName, val, group, primitiveKind);
             obj.TrySetPropertyValue(val.Alias, value);
             targetQueryableDictionary.Add(val.Alias, value);
         }
         else
         {
             object value;
             if (val.MethodDefinition.MethodLabel.Contains(ODataFilterConstants.AggregationMethod_Custom_List, StringComparison.OrdinalIgnoreCase))
             {
                 value = GetAggregatedValue(property.Key, val, group, EdmPrimitiveTypeKind.None, edmComplexType);
                 var subcollectionContext = (SubCollectionContext)value;
                 obj.TrySetPropertyValue(property.Key, subcollectionContext.Result);
                 targetQueryableDictionary.Add(property.Key, subcollectionContext.QueryAbleResult);
             }
             else if (val.MethodDefinition.MethodLabel.Contains(ODataFilterConstants.AggregationMethod_Custom_CountDistinct, StringComparison.OrdinalIgnoreCase) ||
                      val.MethodDefinition.MethodLabel.Contains(ODataFilterConstants.AggregationMethod_Custom_Count, StringComparison.OrdinalIgnoreCase))
             {
                 var sourcePropertyName = ((SingleValuePropertyAccessNode)val.Expression).Property.Name;
                 value = GetAggregatedValue(sourcePropertyName, val, group, EdmPrimitiveTypeKind.None);
                 obj.TrySetPropertyValue(val.Alias, value);
                 targetQueryableDictionary.Add(val.Alias, value);
             }
         }
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Создание сущности и всех связанных. При существовании в БД произойдёт обновление.
        /// </summary>
        /// <param name="edmEntity"> Создаваемая сущность. </param>
        /// <returns> Созданная сущность. </returns>
        public HttpResponseMessage Post([FromBody] EdmEntityObject edmEntity)
        {
            try
            {
                if (edmEntity == null)
                {
                    edmEntity = ReplaceOdataBindNull();
                }

                DataObject obj = UpdateObject(edmEntity, null);
                ExecuteCallbackAfterCreate(obj);

                edmEntity = GetEdmObject(_model.GetEdmEntityType(type), obj, 1, null, null);
                var responseForPreferMinimal = TestPreferMinimal();
                if (responseForPreferMinimal != null)
                {
                    return(responseForPreferMinimal);
                }

                var result = Request.CreateResponse(System.Net.HttpStatusCode.Created, edmEntity);

                /*
                 * //Для вставки произвольных метаданых в JSON-ответ сервера OData можно использовать следующий код:
                 * var taskResult = result.Content.ReadAsStringAsync().Result; // получить string JSON-ответа
                 * // ... выполнить необходимые действия с JSON
                 * result.Content = new StringContent(taskResult, Encoding.UTF8, "application/json"); // вставить обратно окончательный JSON-ответ
                 */
                if (Request.Headers.Contains("Prefer"))
                {
                    result.Headers.Add("Preference-Applied", "return=representation");
                }

                return(result);
            }
            catch (Exception ex)
            {
                return(InternalServerErrorMessage(ex));
            }
        }
        public IHttpActionResult GetNavigation(string key, string navigation)
        {
            ODataPath path = Request.ODataProperties().Path;

            if (path.PathTemplate != "~/entityset/key/navigation")
            {
                return(BadRequest("Not the correct navigation property access request!"));
            }

            NavigationPropertySegment property = path.Segments.Last() as NavigationPropertySegment;

            if (property == null)
            {
                return(BadRequest("Not the correct navigation property access request!"));
            }

            IEdmEntityType entityType = property.NavigationProperty.DeclaringType as IEdmEntityType;

            EdmEntityObject entity = new EdmEntityObject(entityType);

            DataSourceProvider.Get((string)Request.Properties[Constants.ODataDataSource], key, entity);

            object value = DataSourceProvider.GetProperty((string)Request.Properties[Constants.ODataDataSource], navigation, entity);

            if (value == null)
            {
                return(NotFound());
            }

            IEdmEntityObject nav = value as IEdmEntityObject;

            if (nav == null)
            {
                return(NotFound());
            }

            return(Ok(nav));
        }
Esempio n. 5
0
        public IHttpActionResult GetColor(int key)
        {
            EdmEntityObjectCollection customers = GetCustomers();
            EdmEntityObject           customer  = customers.FirstOrDefault(e =>
            {
                object customerId;
                if (e.TryGetPropertyValue("CustomerId", out customerId))
                {
                    return((int)customerId == key);
                }

                return(false);
            }) as EdmEntityObject;

            if (customer == null)
            {
                return(NotFound());
            }

            object color;

            customer.TryGetPropertyValue("Color", out color);
            if (color == null)
            {
                return(NotFound());
            }

            // return Ok(color, color.GetType());

            EdmEnumObject enumColor = color as EdmEnumObject;

            if (enumColor == null)
            {
                return(NotFound());
            }

            return(Ok(enumColor));
        }
Esempio n. 6
0
        private EdmEntityObject CreateEdmEntity(IEdmEntityType entityType, IDictionary <string, object> rows, Dictionary <string, ComponentHelpClass> columnMap)
        {
            if (rows == null)
            {
                return(null);
            }

            var entity = new EdmEntityObject(entityType);

            foreach (var o in rows)
            {
                if (o.Key.Contains(_separator) == false)
                {
                    entity.TrySetPropertyValue(o.Key, o.Value);
                }
                else
                {
                    ParseComponent(entity, columnMap[o.Key], o.Value);
                }
            }

            return(entity);
        }
Esempio n. 7
0
        // odata/{datasource}/{entityset}({key})/{navigation}
        public IActionResult GetNavigation(string datasource, string key, string navigation)
        {
            ODataPath path = Request.ODataFeature().Path;

            NavigationPropertySegment property = path.Last() as NavigationPropertySegment;

            if (property == null)
            {
                return(BadRequest("Not the correct navigation property access request!"));
            }

            IEdmEntityType entityType = property.NavigationProperty.DeclaringType as IEdmEntityType;

            //Set the SelectExpandClause on OdataFeature to include navigation property set in the $expand
            SetSelectExpandClauseOnODataFeature(path, entityType);

            EdmEntityObject entity = new EdmEntityObject(entityType);
            IDataSource     ds     = _provider.DataSources[datasource];

            ds.Get(key, entity);

            object value = ds.GetProperty(navigation, entity);

            if (value == null)
            {
                return(NotFound());
            }

            IEdmEntityObject nav = value as IEdmEntityObject;

            if (nav == null)
            {
                return(NotFound());
            }

            return(Ok(nav));
        }
        public IHttpActionResult Get()
        {
            IEdmModel model = Request.ODataProperties().Model;
            IEdmEntityType customerType = model.SchemaElements.OfType<IEdmEntityType>().First(e => e.Name == "Customer");

            EdmEntityObject customer = new EdmEntityObject(customerType);

            customer.TrySetPropertyValue("Id", 1);
            customer.TrySetPropertyValue("Tony", 1);

            EdmEntityObjectCollection customers =
                new EdmEntityObjectCollection(
                    new EdmCollectionTypeReference(new EdmCollectionType(customerType.ToEdmTypeReference(false))));
            customers.Add(customer);
            return Ok(customers);

        }
Esempio n. 9
0
        /// <summary>
        /// Десериализует navigation property.
        /// Также выполняет необходимые действия, чтобы обработка @odata.bind выполнялась по стандарту OData.
        /// </summary>
        /// <param name="entityResource">Объект, в который navigation property будет прочитано.</param>
        /// <param name="navigationLinkWrapper">navigation линк.</param>
        /// <param name="entityType">Тип сущности.</param>
        /// <param name="readContext">Состояние и установки, используемые при чтении.</param>
        public override void ApplyNavigationProperty(
            object entityResource,
            ODataNavigationLinkWithItems navigationLinkWrapper,
            IEdmEntityTypeReference entityType,
            ODataDeserializerContext readContext)
        {
            base.ApplyNavigationProperty(entityResource, navigationLinkWrapper, entityType, readContext);
            EdmEntityObject    edmEntity = (EdmEntityObject)entityResource;
            DataObjectEdmModel model     = readContext.Model as DataObjectEdmModel;

            foreach (var childItem in navigationLinkWrapper.NestedItems)
            {
                if (!readContext.Request.Properties.ContainsKey(Dictionary))
                {
                    readContext.Request.Properties.Add(Dictionary, new Dictionary <string, object>());
                }

                var dictionary             = (Dictionary <string, object>)readContext.Request.Properties[Dictionary];
                var navigationPropertyName = navigationLinkWrapper.NavigationLink.Name;
                var entityReferenceLink    = childItem as ODataEntityReferenceLinkBase;

                if (entityReferenceLink != null)
                {
                    Uri referencedEntityUrl = entityReferenceLink.EntityReferenceLink.Url;
                    if (referencedEntityUrl.IsAbsoluteUri)
                    {
                        referencedEntityUrl = referencedEntityUrl.MakeRelativeUri(readContext.Request.RequestUri);
                    }

                    var segments = referencedEntityUrl.OriginalString.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
                    if (segments.Length != 2)
                    {
                        throw new ApplicationException($"Invalid @odata.bind: {referencedEntityUrl.OriginalString}");
                    }

                    var type = model.GetDataObjectType(segments[0]);
                    if (type == null)
                    {
                        throw new ApplicationException($"Invalid entity set: {segments[0]}");
                    }

                    Guid guid;
                    try
                    {
                        guid = new Guid(segments[1]);
                    }
                    catch (Exception)
                    {
                        throw new ApplicationException($"Invalid guid: {segments[1]}");
                    }

                    var linkedEdmEntity = new EdmEntityObject(model.GetEdmEntityType(type));
                    linkedEdmEntity.TrySetPropertyValue("__PrimaryKey", guid);
                    edmEntity.TrySetPropertyValue(navigationPropertyName, linkedEdmEntity);
                    if (!dictionary.ContainsKey(navigationPropertyName))
                    {
                        dictionary.Add(navigationPropertyName, navigationPropertyName);
                    }
                }

                var feed = childItem as ODataFeedWithEntries;
                if (childItem == null || (feed != null && feed.Entries.Count == 0))
                {
                    edmEntity.TrySetPropertyValue(navigationPropertyName, null);
                    if (!dictionary.ContainsKey(navigationPropertyName))
                    {
                        dictionary.Add(navigationPropertyName, null);
                    }
                }
            }
        }
 public IHttpActionResult EntityFunction(int key, [FromODataUri] EdmEntityObject customer, [FromODataUri] EdmEntityObjectCollection customerList)
 {
     return(null);
 }
        public void AfterSavePostComplexObjectTest()
        {
            // TODO: переписать тест с корректным формированием параметра - передаваемой сущности - для Post.
            // Объекты для тестирования создания.
            Медведь медв = new Медведь {
                Вес = 48
            };
            Лес лес1 = new Лес {
                Название = "Бор"
            };
            Лес лес2 = new Лес {
                Название = "Березовая роща"
            };

            медв.ЛесОбитания = лес1;
            var берлога1 = new Берлога {
                Наименование = "Для хорошего настроения", ЛесРасположения = лес1
            };
            var берлога2 = new Берлога {
                Наименование = "Для плохого настроения", ЛесРасположения = лес2
            };

            медв.Берлога.Add(берлога1);
            медв.Берлога.Add(берлога2);

            // Объекты для тестирования создания с обновлением.
            Медведь медвежонок = new Медведь {
                Вес = 12
            };
            var берлога3 = new Берлога {
                Наименование = "Для хорошего настроения", ЛесРасположения = лес1
            };

            медвежонок.Берлога.Add(берлога3);

            ActODataService(args =>
            {
                args.Token.Events.CallbackAfterCreate = AfterCreate;
                args.Token.Events.CallbackAfterUpdate = AfterUpdate;
                args.Token.Events.CallbackAfterDelete = AfterDelete;

                // ------------------ Только создания объектов ------------------
                // Подготовка тестовых данных в формате OData.
                var controller         = new DataObjectController(args.DataService, args.Token.Model, args.Token.Events, args.Token.Functions);
                EdmEntityObject edmObj = controller.GetEdmObject(args.Token.Model.GetEdmEntityType(typeof(Медведь)), медв, 1, null);
                var edmЛес1            = controller.GetEdmObject(args.Token.Model.GetEdmEntityType(typeof(Лес)), лес1, 1, null);
                var edmЛес2            = controller.GetEdmObject(args.Token.Model.GetEdmEntityType(typeof(Лес)), лес2, 1, null);
                edmObj.TrySetPropertyValue("ЛесОбитания", edmЛес1);
                var coll = controller.GetEdmCollection(медв.Берлога, typeof(Берлога), 1, null);
                edmObj.TrySetPropertyValue("Берлога", coll);
                EdmEntityObject edmБерлога1 = (EdmEntityObject)coll[0]; // controller.GetEdmObject(args.ODataService.Model.GetEdmEntityType(typeof(Берлога)), берлога1, 1, null);
                EdmEntityObject edmБерлога2 = (EdmEntityObject)coll[1]; // controller.GetEdmObject(args.ODataService.Model.GetEdmEntityType(typeof(Берлога)), берлога2, 1, null);
                edmБерлога1.TrySetPropertyValue("ЛесРасположения", edmЛес1);
                edmБерлога2.TrySetPropertyValue("ЛесРасположения", edmЛес2);

                // Формируем URL запроса к OData-сервису.
                string requestUrl = string.Format("http://localhost/odata/{0}", args.Token.Model.GetEdmEntitySet(typeof(Медведь)).Name);

                ParamObj = null;

                // Обращаемся к OData-сервису и обрабатываем ответ, в теле запроса передаем создаваемый объект в формате JSON.
                HttpResponseMessage response = args.HttpClient.PostAsJsonAsync(requestUrl, edmObj).Result;
                Assert.NotNull(ParamObj);

                // Убедимся, что запрос завершился успешно.
                Assert.Equal(HttpStatusCode.Created, response.StatusCode);

                // Получим строку с ответом.
                string receivedJsonObjs = response.Content.ReadAsStringAsync().Result.Beautify();

                // В ответе приходит объект с созданной сущностью.
                // Преобразуем полученный объект в словарь.
                Dictionary <string, object> receivedObjs = new JavaScriptSerializer().Deserialize <Dictionary <string, object> >(receivedJsonObjs);

                // Проверяем созданный объект, вычитав с помощью DataService
                DataObject createdObj = new Медведь {
                    __PrimaryKey = медв.__PrimaryKey
                };
                args.DataService.LoadObject(createdObj);

                Assert.Equal(ObjectStatus.UnAltered, createdObj.GetStatus());
                Assert.Equal(((Медведь)createdObj).Вес, receivedObjs["Вес"]);

                // Проверяем что созданы все зависимые объекты, вычитав с помощью DataService
                var ldef         = ICSSoft.STORMNET.FunctionalLanguage.SQLWhere.SQLWhereLanguageDef.LanguageDef;
                var lcs          = LoadingCustomizationStruct.GetSimpleStruct(typeof(Лес), "ЛесE");
                lcs.LoadingTypes = new[] { typeof(Лес) };
                var dobjs        = args.DataService.LoadObjects(lcs);

                Assert.Equal(2, dobjs.Length);

                lcs = LoadingCustomizationStruct.GetSimpleStruct(typeof(Берлога), "БерлогаE");
                lcs.LoadingTypes = new[] { typeof(Берлога) };

                // lcs.LimitFunction = ldef.GetFunction(ldef.funcEQ, new VariableDef(ldef.GuidType, SQLWhereLanguageDef.StormMainObjectKey), keyValue);
                dobjs = args.DataService.LoadObjects(lcs);
                Assert.Equal(2, dobjs.Length);

                // ------------------ Создание объекта и обновление связанных ------------------
                // Создаем нового медведя: в его мастере ЛесОбитания - лес1, но в нём изменим Название; в детейлы заберем от первого медведя  детейл2, изменив Название в мастере детейла.
                // Подготовка тестовых данных в формате OData.
                edmObj = controller.GetEdmObject(args.Token.Model.GetEdmEntityType(typeof(Медведь)), медвежонок, 1, null);
                edmObj.TrySetPropertyValue("ЛесОбитания", edmЛес1);
                edmЛес1.TrySetPropertyValue("Название", лес1.Название + "(обновл)");
                edmЛес2.TrySetPropertyValue("Название", лес2.Название + "(обновл)");
                медв.Берлога.Remove(берлога2);
                медвежонок.Берлога.Add(берлога2);
                coll = controller.GetEdmCollection(медвежонок.Берлога, typeof(Берлога), 1, null);
                edmObj.TrySetPropertyValue("Берлога", coll);
                edmБерлога1 = (EdmEntityObject)coll[0];
                edmБерлога2 = (EdmEntityObject)coll[1];
                edmБерлога1.TrySetPropertyValue("ЛесРасположения", edmЛес2);
                edmБерлога2.TrySetPropertyValue("ЛесРасположения", edmЛес1);

                ParamObj = null;

                // Обращаемся к OData-сервису и обрабатываем ответ, в теле запроса передаем создаваемый объект в формате JSON.
                response = args.HttpClient.PostAsJsonAsync(requestUrl, edmObj).Result;
                Assert.NotNull(ParamObj);

                // Убедимся, что запрос завершился успешно.
                Assert.Equal(HttpStatusCode.Created, response.StatusCode);

                // Проверяем созданный объект, вычитав с помощью DataService
                createdObj = new Медведь {
                    __PrimaryKey = медвежонок.__PrimaryKey
                };
                args.DataService.LoadObject(createdObj);

                Assert.Equal(ObjectStatus.UnAltered, createdObj.GetStatus());
                Assert.Equal(12, ((Медведь)createdObj).Вес);

                // Проверяем что созданы все зависимые объекты, вычитав с помощью DataService
                ldef              = ICSSoft.STORMNET.FunctionalLanguage.SQLWhere.SQLWhereLanguageDef.LanguageDef;
                lcs               = LoadingCustomizationStruct.GetSimpleStruct(typeof(Лес), "ЛесE");
                lcs.LoadingTypes  = new[] { typeof(Лес) };
                lcs.LimitFunction = ldef.GetFunction(
                    ldef.funcEQ,
                    new ICSSoft.STORMNET.FunctionalLanguage.VariableDef(ldef.GuidType, ICSSoft.STORMNET.FunctionalLanguage.SQLWhere.SQLWhereLanguageDef.StormMainObjectKey),
                    лес1.__PrimaryKey);
                dobjs = args.DataService.LoadObjects(lcs);

                Assert.Equal(1, dobjs.Length);
                Assert.True(((Лес)dobjs[0]).Название.EndsWith("(обновл)"));

                lcs.LimitFunction = ldef.GetFunction(
                    ldef.funcEQ,
                    new ICSSoft.STORMNET.FunctionalLanguage.VariableDef(ldef.GuidType, ICSSoft.STORMNET.FunctionalLanguage.SQLWhere.SQLWhereLanguageDef.StormMainObjectKey),
                    лес2.__PrimaryKey);
                dobjs = args.DataService.LoadObjects(lcs);

                Assert.Equal(1, dobjs.Length);
                Assert.True(((Лес)dobjs[0]).Название.EndsWith("(обновл)"));

                lcs = LoadingCustomizationStruct.GetSimpleStruct(typeof(Берлога), "БерлогаE");
                lcs.LoadingTypes  = new[] { typeof(Берлога) };
                lcs.LimitFunction = ldef.GetFunction(
                    ldef.funcEQ,
                    new ICSSoft.STORMNET.FunctionalLanguage.VariableDef(ldef.GuidType, "Медведь"),
                    медв.__PrimaryKey);
                dobjs = args.DataService.LoadObjects(lcs);

                Assert.Equal(1, dobjs.Length);

                lcs.LimitFunction = ldef.GetFunction(
                    ldef.funcEQ,
                    new ICSSoft.STORMNET.FunctionalLanguage.VariableDef(ldef.GuidType, "Медведь"),
                    медвежонок.__PrimaryKey);
                dobjs = args.DataService.LoadObjects(lcs);

                Assert.Equal(2, dobjs.Length);

                // Вернем детейл для того, чтобы тест работал со следующими СУБД.
                медвежонок.Берлога.Remove(берлога2);
                медв.Берлога.Add(берлога2);
            });
        }
 public bool EntityFunctionOnAttribute(int key, [FromODataUri] EdmEntityObject customer)
 {
     return(EntityFunction(key, customer));
 }
 public void Get(string key, EdmEntityObject entity)
 {
     _dataSource.Get(key, entity);
 }
Esempio n. 14
0
 /// <summary>
 /// Handles a PATCH request to partially update an entity.
 /// </summary>
 /// <param name="edmEntityObject">The entity object to update.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>The task object that contains the updated result.</returns>
 public async Task <IHttpActionResult> Patch(EdmEntityObject edmEntityObject, CancellationToken cancellationToken) => await Update(edmEntityObject, false, cancellationToken).ConfigureAwait(false);
Esempio n. 15
0
        public IActionResult PostUntypedSimpleOpenCustomer(EdmEntityObject customer)
        {
            // Verify there is a string dynamic property in OpenEntityType
            object nameValue;

            customer.TryGetPropertyValue("Name", out nameValue);
            Type nameType;

            customer.TryGetPropertyType("Name", out nameType);

            Assert.NotNull(nameValue);
            Assert.Equal(typeof(String), nameType);
            Assert.Equal("FirstName 6", nameValue);

            // Verify there is a collection of double dynamic property in OpenEntityType
            object doubleListValue;

            customer.TryGetPropertyValue("DoubleList", out doubleListValue);
            Type doubleListType;

            customer.TryGetPropertyType("DoubleList", out doubleListType);

            Assert.NotNull(doubleListValue);
            Assert.Equal(typeof(List <Double>), doubleListType);

            // Verify there is a collection of complex type dynamic property in OpenEntityType
            object addressesValue;

            customer.TryGetPropertyValue("Addresses", out addressesValue);

            Assert.NotNull(addressesValue);

            // Verify there is a complex type dynamic property in OpenEntityType
            object addressValue;

            customer.TryGetPropertyValue("Address", out addressValue);

            Type addressType;

            customer.TryGetPropertyType("Address", out addressType);

            Assert.NotNull(addressValue);
            Assert.Equal(typeof(EdmComplexObject), addressType);

            // Verify there is a collection of enum type dynamic property in OpenEntityType
            object favoriteColorsValue;

            customer.TryGetPropertyValue("FavoriteColors", out favoriteColorsValue);
            EdmEnumObjectCollection favoriteColors = favoriteColorsValue as EdmEnumObjectCollection;

            Assert.NotNull(favoriteColorsValue);
            Assert.NotNull(favoriteColors);
            Assert.Equal(typeof(EdmEnumObject), favoriteColors[0].GetType());

            // Verify there is an enum type dynamic property in OpenEntityType
            object favoriteColorValue;

            customer.TryGetPropertyValue("FavoriteColor", out favoriteColorValue);

            Assert.NotNull(favoriteColorValue);
            Assert.Equal("Red", ((EdmEnumObject)favoriteColorValue).Value);

            Type favoriteColorType;

            customer.TryGetPropertyType("FavoriteColor", out favoriteColorType);

            Assert.Equal(typeof(EdmEnumObject), favoriteColorType);

            // Verify there is a string dynamic property in OpenComplexType
            EdmComplexObject address = addressValue as EdmComplexObject;
            object           cityValue;

            address.TryGetPropertyValue("City", out cityValue);
            Type cityType;

            address.TryGetPropertyType("City", out cityType);

            Assert.NotNull(cityValue);
            Assert.Equal(typeof(String), cityType);
            Assert.Equal("City 6", cityValue); // It reads as ODataUntypedValue, and the RawValue is the string with the ""

            return(Ok(customer));
        }
Esempio n. 16
0
 /// <summary>
 /// Handles a PATCH request to partially update an entity.
 /// </summary>
 /// <param name="edmEntityObject">The entity object to update.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 /// <returns>The task object that contains the updated result.</returns>
 public async Task <IHttpActionResult> Patch(EdmEntityObject edmEntityObject, CancellationToken cancellationToken)
 {
     return(await this.Update(edmEntityObject, false, cancellationToken));
 }
 public void Get(string key, EdmEntityObject entity)
 {
     entity.TrySetPropertyValue("Name", "abc");
     entity.TrySetPropertyValue("ID", int.Parse(key));
     entity.TrySetPropertyValue("DetailInfo", CreateDetailInfo(88, "abc_detailinfo", entity.ActualEdmType));
 }
Esempio n. 18
0
 public static object GetProperty(string dataSourceName, string property, EdmEntityObject entity)
 {
     return(GetDataSource(dataSourceName).GetProperty(property, entity));
 }
Esempio n. 19
0
 public static void Get(string dataSourceName, string key, EdmEntityObject entity)
 {
     GetDataSource(dataSourceName).Get(key, entity);
 }
Esempio n. 20
0
        public ParseContext Parse(ODataUriParser parser, ParseContext sourceParseContext)
        {
            //Select implementation
            var targetParseContext            = new ParseContext();
            var targetQueryableSourceEntities = new List <Dictionary <string, object> >();
            var sourceEdmSetting = sourceParseContext.EdmEntityTypeSettings.FirstOrDefault();
            var targetEdmSetting = new EdmEntityTypeSettings()
            {
                RouteName  = SelectParser,
                Personas   = sourceEdmSetting.Personas,
                Properties = new List <EdmEntityTypePropertySetting>()
            };
            var selectExpandClause    = parser.ParseSelectAndExpand();
            var edmEntityType         = new EdmEntityType(EdmNamespaceName, SelectParser);
            var latestStateDictionary = new Dictionary <string, object>();

            //Construct the types. For now we support non-nested primitive types only. Everything else is an exception for now.
            var propertyList = new List <string>();

            foreach (var item in selectExpandClause.SelectedItems)
            {
                switch (item)
                {
                case PathSelectItem pathSelectItem:
                    IEnumerable <ODataPathSegment> segments = pathSelectItem.SelectedPath;
                    var firstPropertySegment = segments.FirstOrDefault();
                    if (firstPropertySegment != null)
                    {
                        var typeSetting = sourceEdmSetting.Properties.FirstOrDefault(predicate => predicate.PropertyName == firstPropertySegment.Identifier);

                        propertyList.Add(firstPropertySegment.Identifier);

                        if (typeSetting.GetEdmPrimitiveTypeKind() != EdmPrimitiveTypeKind.None)
                        {
                            var edmPrimitiveType = typeSetting.GetEdmPrimitiveTypeKind();
                            if (typeSetting.IsNullable.HasValue)
                            {
                                edmEntityType.AddStructuralProperty(firstPropertySegment.Identifier, edmPrimitiveType, typeSetting.IsNullable.Value);
                            }
                            else
                            {
                                edmEntityType.AddStructuralProperty(firstPropertySegment.Identifier, edmPrimitiveType);
                            }
                            targetEdmSetting.Properties.Add(new EdmEntityTypePropertySetting
                            {
                                PropertyName = typeSetting.PropertyName,
                                PropertyType = typeSetting.PropertyType,
                                IsNullable   = typeSetting.IsNullable
                            });
                        }
                        else
                        {
                            //We are doing $select on a property which is of type list. Which means
                            if (typeSetting.PropertyType == "List")
                            {
                                var edmComplexType = GetEdmComplexTypeReference(sourceParseContext);
                                edmEntityType.AddStructuralProperty(typeSetting.PropertyName, new EdmCollectionTypeReference(new EdmCollectionType(new EdmComplexTypeReference(edmComplexType, true))));
                                targetEdmSetting.Properties.Add(new EdmEntityTypePropertySetting
                                {
                                    PropertyName = typeSetting.PropertyName,
                                    PropertyType = typeSetting.PropertyType,
                                    IsNullable   = typeSetting.IsNullable
                                });
                            }
                            else
                            {
                                throw new FeatureNotSupportedException(SelectParser, $"Invalid Custom Selection-{typeSetting.PropertyName}-{typeSetting.PropertyType}");
                            }
                        }
                    }
                    else
                    {
                        throw new FeatureNotSupportedException(SelectParser, "Empty Path Segments");
                    }
                    break;

                case WildcardSelectItem wildcardSelectItem: throw new FeatureNotSupportedException(SelectParser, "WildcardSelect");

                case ExpandedNavigationSelectItem expandedNavigationSelectItem: throw new FeatureNotSupportedException(SelectParser, "ExpandedNavigation");

                case ExpandedReferenceSelectItem expandedReferenceSelectItem: throw new FeatureNotSupportedException(SelectParser, "ExpandedReference");

                case NamespaceQualifiedWildcardSelectItem namespaceQualifiedWildcardSelectItem: throw new FeatureNotSupportedException(SelectParser, "NamespaceQualifiedWildcard");
                }
            }

            //Register these dynamic types to model
            sourceParseContext.Model.AddElement(edmEntityType);
            ((EdmEntityContainer)sourceParseContext.Model.EntityContainer).AddEntitySet("Select", edmEntityType);


            //Construct the data
            var entityReferenceType         = new EdmEntityTypeReference(edmEntityType, true);
            var collectionRef               = new EdmCollectionTypeReference(new EdmCollectionType(entityReferenceType));
            var collection                  = new EdmEntityObjectCollection(collectionRef);
            var filteredQueryableEntityList = sourceParseContext.QueryableSourceEntities.Select(p => p.Where(p => propertyList.Contains(p.Key)));

            latestStateDictionary.Add(RequestFilterConstants.GetEntityTypeKeyName(SelectParser, StepIndex), entityReferenceType);

            foreach (var entity in filteredQueryableEntityList)
            {
                var entityDictionary = new Dictionary <string, object>();
                var obj = new EdmEntityObject(edmEntityType);
                foreach (var propertyKey in propertyList)
                {
                    var setting = targetEdmSetting.Properties.FirstOrDefault(predicate => predicate.PropertyName.Equals(propertyKey));
                    var data    = entity.FirstOrDefault(property => property.Key.Equals(propertyKey));

                    //This condition is when the type of selected property is a primitive type
                    if (setting.GetEdmPrimitiveTypeKind() != EdmPrimitiveTypeKind.None)
                    {
                        var propertyValue = !data.Equals(default(KeyValuePair <string, object>)) ? data.Value : null;
                        obj.TrySetPropertyValue(propertyKey, propertyValue);
                        entityDictionary.Add(propertyKey, propertyValue);
                    }
                    else
                    {
                        switch (setting.PropertyType)
                        {
                        case "List":
                            //TODO: There is scope for perf improvement
                            //We can re-use the previous constructed list instead of constructing one from scratch.
                            var subList        = (List <Dictionary <string, object> >)data.Value;
                            var subListContext = GetList(subList, GetEdmComplexTypeReference(sourceParseContext));
                            obj.TrySetPropertyValue(propertyKey, subListContext.Result);
                            entityDictionary.Add(propertyKey, subListContext.QueryAbleResult);
                            break;
                        }
                    }
                }
                collection.Add(obj);
                targetQueryableSourceEntities.Add(entityDictionary);
            }

            targetParseContext.Result = collection;
            targetParseContext.QueryableSourceEntities = targetQueryableSourceEntities;
            targetParseContext.Model = sourceParseContext.Model;
            targetParseContext.EdmEntityTypeSettings = new List <EdmEntityTypeSettings> {
                targetEdmSetting
            };
            targetParseContext.LatestStateDictionary = latestStateDictionary;
            return(targetParseContext);
        }
Esempio n. 21
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);
        }
Esempio n. 22
0
 public void Get(string key, EdmEntityObject entity)
 {
     entity.TrySetPropertyValue("Name", "Foo");
     entity.TrySetPropertyValue("ID", int.Parse(key));
 }
        protected virtual IEdmEntityObject BuildEdmEntityObject(Entity record, SavedQueryView view, IEnumerable <SavedQueryView.ViewColumn> viewColumns, EdmEntityTypeReference dataEntityTypeReference, EdmComplexTypeReference entityReferenceComplexTypeReference, EdmComplexTypeReference optionSetComplexTypeReference, string entityListIdString, string viewIdString)
        {
            if (record == null)
            {
                return(null);
            }

            var entityObject = new EdmEntityObject(dataEntityTypeReference);

            entityObject.TrySetPropertyValue(view.PrimaryKeyLogicalName, record.Id);

            foreach (var column in viewColumns)
            {
                var value = record.Attributes.Contains(column.LogicalName) ? record.Attributes[column.LogicalName] : null;

                if (value is AliasedValue)
                {
                    var aliasedValue = value as AliasedValue;
                    value = aliasedValue.Value;
                }

                if (column.Metadata == null)
                {
                    continue;
                }

                var propertyName = column.LogicalName;

                if (propertyName.Contains('.'))
                {
                    propertyName = string.Format("{0}-{1}", column.Metadata.EntityLogicalName, column.Metadata.LogicalName);
                }

                switch (column.Metadata.AttributeType)
                {
                case AttributeTypeCode.Money:
                    var     money      = value as Money;
                    decimal moneyValue = 0;
                    if (money != null)
                    {
                        moneyValue = money.Value;
                    }
                    entityObject.TrySetPropertyValue(propertyName, moneyValue);
                    break;

                case AttributeTypeCode.Customer:
                case AttributeTypeCode.Lookup:
                case AttributeTypeCode.Owner:
                    var entityReference = value as EntityReference;
                    if (entityReference == null)
                    {
                        continue;
                    }
                    var entityReferenceObject = new EdmComplexObject(entityReferenceComplexTypeReference);
                    entityReferenceObject.TrySetPropertyValue("Name", entityReference.Name);
                    entityReferenceObject.TrySetPropertyValue("Id", entityReference.Id);
                    entityObject.TrySetPropertyValue(propertyName, entityReferenceObject);
                    break;

                case AttributeTypeCode.State:
                    var stateOptionSet = value as OptionSetValue;
                    if (stateOptionSet == null)
                    {
                        continue;
                    }
                    var stateAttributeMetadata = column.Metadata as StateAttributeMetadata;
                    if (stateAttributeMetadata == null)
                    {
                        continue;
                    }
                    var stateOption = stateAttributeMetadata.OptionSet.Options.FirstOrDefault(o => o != null && o.Value != null && o.Value.Value == stateOptionSet.Value);
                    if (stateOption == null)
                    {
                        continue;
                    }
                    var stateLabel      = stateOption.Label.LocalizedLabels.FirstOrDefault(l => l.LanguageCode == LanguageCode) ?? stateOption.Label.GetLocalizedLabel();
                    var stateOptionName = stateLabel == null?stateOption.Label.GetLocalizedLabelString() : stateLabel.Label;

                    var stateOptionSetObject = new EdmComplexObject(optionSetComplexTypeReference);
                    stateOptionSetObject.TrySetPropertyValue("Name", stateOptionName);
                    stateOptionSetObject.TrySetPropertyValue("Value", stateOptionSet.Value);
                    entityObject.TrySetPropertyValue(propertyName, stateOptionSetObject);
                    break;

                case AttributeTypeCode.Picklist:
                    var optionSet = value as OptionSetValue;
                    if (optionSet == null)
                    {
                        continue;
                    }
                    var picklistAttributeMetadata = column.Metadata as PicklistAttributeMetadata;
                    if (picklistAttributeMetadata == null)
                    {
                        continue;
                    }
                    var option = picklistAttributeMetadata.OptionSet.Options.FirstOrDefault(o => o != null && o.Value != null && o.Value.Value == optionSet.Value);
                    if (option == null)
                    {
                        continue;
                    }
                    var label = option.Label.LocalizedLabels.FirstOrDefault(l => l.LanguageCode == LanguageCode) ?? option.Label.GetLocalizedLabel();
                    var name  = label == null?option.Label.GetLocalizedLabelString() : label.Label;

                    var optionSetObject = new EdmComplexObject(optionSetComplexTypeReference);
                    optionSetObject.TrySetPropertyValue("Name", name);
                    optionSetObject.TrySetPropertyValue("Value", optionSet.Value);
                    entityObject.TrySetPropertyValue(propertyName, optionSetObject);
                    break;

                case AttributeTypeCode.Status:
                    var statusOptionSet = value as OptionSetValue;
                    if (statusOptionSet == null)
                    {
                        continue;
                    }
                    var statusAttributeMetadata = column.Metadata as StatusAttributeMetadata;
                    if (statusAttributeMetadata == null)
                    {
                        continue;
                    }
                    var statusOption = statusAttributeMetadata.OptionSet.Options.FirstOrDefault(o => o != null && o.Value != null && o.Value.Value == statusOptionSet.Value);
                    if (statusOption == null)
                    {
                        continue;
                    }
                    var statusLabel      = statusOption.Label.LocalizedLabels.FirstOrDefault(l => l.LanguageCode == LanguageCode) ?? statusOption.Label.GetLocalizedLabel();
                    var statusOptionName = statusLabel == null?statusOption.Label.GetLocalizedLabelString() : statusLabel.Label;

                    var statusOptionSetObject = new EdmComplexObject(optionSetComplexTypeReference);
                    statusOptionSetObject.TrySetPropertyValue("Name", statusOptionName);
                    statusOptionSetObject.TrySetPropertyValue("Value", statusOptionSet.Value);
                    entityObject.TrySetPropertyValue(propertyName, statusOptionSetObject);
                    break;

                default:
                    entityObject.TrySetPropertyValue(propertyName, value);
                    break;
                }
                entityObject.TrySetPropertyValue("list-id", entityListIdString);
                entityObject.TrySetPropertyValue("view-id", viewIdString);
            }
            return(entityObject);
        }
Esempio n. 24
0
 public void Get(string key, EdmEntityObject entity)
 {
     throw new NotImplementedException();
 }
Esempio n. 25
0
        private async Task <IHttpActionResult> Update(
            EdmEntityObject edmEntityObject,
            bool isFullReplaceUpdate,
            CancellationToken cancellationToken)
        {
            CheckModelState();
            var path      = GetPath();
            var entitySet = path.NavigationSource as IEdmEntitySet;

            if (entitySet == null)
            {
                throw new NotImplementedException(Resources.UpdateOnlySupportedOnEntitySet);
            }

            var propertiesInEtag = await GetOriginalValues(entitySet).ConfigureAwait(false);

            if (propertiesInEtag == null)
            {
                throw new PreconditionRequiredException(Resources.PreconditionRequired);
            }

            // In case of type inheritance, the actual type will be different from entity type
            // This is only needed for put case, and does not need for patch case
            // For put request, it will create a new, blank instance of the entity.
            // copy over the key values and set any updated values from the client on the new instance.
            // Then apply all the properties of the new instance to the instance to be updated.
            // This will set any unspecified properties to their default value.
            var expectedEntityType = path.EdmType;
            var actualEntityType   = path.EdmType as IEdmStructuredType;

            if (edmEntityObject.ActualEdmType != null)
            {
                expectedEntityType = edmEntityObject.ExpectedEdmType;
                actualEntityType   = edmEntityObject.ActualEdmType;
            }

            var updateItem = new DataModificationItem(
                entitySet.Name,
                expectedEntityType.GetClrType(Api.ServiceProvider),
                actualEntityType.GetClrType(Api.ServiceProvider),
                RestierEntitySetOperation.Update,
                RestierQueryBuilder.GetPathKeyValues(path),
                propertiesInEtag,
                edmEntityObject.CreatePropertyDictionary(actualEntityType, api, false))
            {
                IsFullReplaceUpdateRequest = isFullReplaceUpdate
            };

            var changeSetProperty = Request.GetChangeSet();

            if (changeSetProperty == null)
            {
                var changeSet = new ChangeSet();
                changeSet.Entries.Add(updateItem);

                var result = await Api.SubmitAsync(changeSet, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                changeSetProperty.ChangeSet.Entries.Add(updateItem);

                await changeSetProperty.OnChangeSetCompleted(Request).ConfigureAwait(false);
            }

            return(CreateUpdatedODataResult(updateItem.Resource));
        }
Esempio n. 26
0
 public object GetProperty(string property, EdmEntityObject entity)
 {
     throw new NotImplementedException();
 }
Esempio n. 27
0
 public void Get(string key, EdmEntityObject entity)
 {
     entity.TrySetPropertyValue("Name", "Foo");
     entity.TrySetPropertyValue("ID", int.Parse(key));
     entity.TrySetPropertyValue("School", Createchool(99, new DateTimeOffset(2016, 1, 19, 1, 2, 3, TimeSpan.Zero), entity.ActualEdmType));
 }
Esempio n. 28
0
        public ParseContext Parse(ODataUriParser parser, ParseContext sourceParseContext)
        {
            SourceParseContext = sourceParseContext;
            var targetParseContext            = new ParseContext();
            var targetQueryableSourceEntities = new List <Dictionary <string, object> >();
            var sourceEdmSetting = sourceParseContext.EdmEntityTypeSettings.FirstOrDefault();
            var targetEdmSetting = new EdmEntityTypeSettings()
            {
                RouteName  = "Groups",
                Personas   = sourceEdmSetting.Personas,
                Properties = new List <EdmEntityTypePropertySetting>()
            };
            var latestStateDictionary = new Dictionary <string, object>();

            var edmEntityType = new EdmEntityType(EdmNamespaceName, "Groups");
            //This may only be used if we client uses Custom.List as aggregation
            var edmComplexType    = new EdmComplexType(EdmNamespaceName, "List");
            var aggregatePropList = new Dictionary <string, AggregateExpression>();
            var applyClause       = parser.ParseApply();

            //We support only single transformation
            if (applyClause.Transformations.Count() > 1)
            {
                throw new FeatureNotSupportedException(ApplyParser, "Multiple Transformations");
            }

            if (applyClause.Transformations.Count() == 0)
            {
                throw new FeatureNotSupportedException(ApplyParser, "Zero Transformations");
            }

            foreach (var transformation in applyClause.Transformations)
            {
                if (transformation.Kind == TransformationNodeKind.GroupBy)
                {
                    var transform = (GroupByTransformationNode)transformation;

                    ///Add all the grouping properties
                    foreach (var groupingProperty in transform.GroupingProperties)
                    {
                        var sourceProperty = sourceEdmSetting.Properties.FirstOrDefault(predicate => predicate.PropertyName.Equals(groupingProperty.Name));

                        edmEntityType.AddStructuralProperty(groupingProperty.Name, groupingProperty.TypeReference.PrimitiveKind());

                        targetEdmSetting.Properties.Add(new EdmEntityTypePropertySetting
                        {
                            PropertyName = sourceProperty.PropertyName,
                            PropertyType = sourceProperty.PropertyType,
                            IsNullable   = sourceProperty.IsNullable
                        });
                    }


                    //Add all the aggregate properties
                    if (transform.ChildTransformations != null)
                    {
                        var aggregationProperties = (AggregateTransformationNode)transform.ChildTransformations;
                        AddAggregationPropertiesToModel(aggregationProperties
                                                        , sourceEdmSetting, edmEntityType, aggregatePropList, targetEdmSetting
                                                        , edmComplexType, latestStateDictionary);
                    }

                    //Register these dynamic types to model
                    sourceParseContext.Model.AddElement(edmEntityType);
                    sourceParseContext.Model.AddElement(edmComplexType);
                    ((EdmEntityContainer)sourceParseContext.Model.EntityContainer).AddEntitySet("Groups", edmEntityType);

                    var fields = transform.GroupingProperties.Select(p => p.Name).ToList();
                    var groups = sourceParseContext.QueryableSourceEntities
                                 .GroupBy(r => fields.ToDictionary(c => c, c => r[c]), new CustomEqualityComparer());

                    var entityRef     = new EdmEntityTypeReference(edmEntityType, true);
                    var collectionRef = new EdmCollectionTypeReference(new EdmCollectionType(entityRef));
                    var collection    = new EdmEntityObjectCollection(collectionRef);
                    latestStateDictionary.Add(RequestFilterConstants.GetEntityTypeKeyName(ApplyParser, StepIndex), entityRef);
                    foreach (var group in groups)
                    {
                        var targetQueryableDictionary = new Dictionary <string, object>();
                        var obj = new EdmEntityObject(edmEntityType);
                        foreach (var prop in fields)
                        {
                            var value = group.Key[prop];
                            obj.TrySetPropertyValue(prop, value);
                            targetQueryableDictionary.Add(prop, value);
                        }
                        AddAggregationPropertyValuesToModel(targetQueryableDictionary, obj, group, edmComplexType, aggregatePropList);
                        collection.Add(obj);
                        targetQueryableSourceEntities.Add(targetQueryableDictionary);
                    }
                    targetParseContext.Result = collection;
                    targetParseContext.Model  = sourceParseContext.Model;
                    targetParseContext.QueryableSourceEntities = targetQueryableSourceEntities;
                    targetParseContext.EdmEntityTypeSettings   = new List <EdmEntityTypeSettings> {
                        targetEdmSetting
                    };
                    targetParseContext.LatestStateDictionary = latestStateDictionary;
                    return(targetParseContext);
                }
                else if (transformation.Kind == TransformationNodeKind.Aggregate)
                {
                    var targetQueryableDictionary = new Dictionary <string, object>();
                    var obj = new EdmEntityObject(edmEntityType);
                    var aggregationProperties = (AggregateTransformationNode)transformation;
                    AddAggregationPropertiesToModel(aggregationProperties
                                                    , sourceEdmSetting, edmEntityType, aggregatePropList, targetEdmSetting
                                                    , edmComplexType, latestStateDictionary);
                    //Register these dynamic types to model
                    sourceParseContext.Model.AddElement(edmEntityType);
                    sourceParseContext.Model.AddElement(edmComplexType);
                    var entityRef     = new EdmEntityTypeReference(edmEntityType, true);
                    var collectionRef = new EdmCollectionTypeReference(new EdmCollectionType(entityRef));
                    var collection    = new EdmEntityObjectCollection(collectionRef);
                    latestStateDictionary.Add(RequestFilterConstants.GetEntityTypeKeyName(ApplyParser, StepIndex), entityRef);
                    AddAggregationPropertyValuesToModel(targetQueryableDictionary, obj, sourceParseContext.QueryableSourceEntities, edmComplexType, aggregatePropList);
                    collection.Add(obj);
                    targetQueryableSourceEntities.Add(targetQueryableDictionary);
                    targetParseContext.Result = collection;
                    targetParseContext.Model  = sourceParseContext.Model;
                    targetParseContext.QueryableSourceEntities = targetQueryableSourceEntities;
                    targetParseContext.EdmEntityTypeSettings   = new List <EdmEntityTypeSettings> {
                        targetEdmSetting
                    };
                    targetParseContext.LatestStateDictionary = latestStateDictionary;
                    return(targetParseContext);
                }
                else
                {
                    throw new FeatureNotSupportedException(ApplyParser, $"Transformation Kind {transformation.Kind} is not supported");
                }
            }
            throw new FeatureNotSupportedException(ApplyParser, "Invalid Apply Clause");
        }
Esempio n. 29
0
        public bool CollectionEntityFunction(int key, [FromODataUri] EdmEntityObjectCollection customers)
        {
            Assert.NotNull(customers);
            IList <IEdmEntityObject> results = customers.ToList();

            Assert.Equal(2, results.Count);

            // entities call
            if (key == 9)
            {
                // #1
                EdmEntityObject entity = results[0] as EdmEntityObject;
                Assert.NotNull(entity);
                Assert.Equal("NS.Customer", entity.GetEdmType().FullName());

                dynamic customer = results[0];
                Assert.Equal(91, customer.Id);
                Assert.Equal("John", customer.Name);

                dynamic          address    = customer.Location;
                EdmComplexObject addressObj = Assert.IsType <EdmComplexObject>(address);
                Assert.Equal("NS.Address", addressObj.GetEdmType().FullName());
                Assert.Equal("NE 24th St.", address.Street);
                Assert.Equal("Redmond", address.City);

                // #2
                entity = results[1] as EdmEntityObject;
                Assert.Equal("NS.SpecialCustomer", entity.GetEdmType().FullName());

                customer = results[1];
                Assert.Equal(92, customer.Id);
                Assert.Equal("Mike", customer.Name);

                address    = customer.Location;
                addressObj = Assert.IsType <EdmComplexObject>(address);
                Assert.Equal("NS.SubAddress", addressObj.GetEdmType().FullName());
                Assert.Equal("LianHua Rd.", address.Street);
                Assert.Equal("Shanghai", address.City);
                Assert.Equal(9.9, address.Code);

                Assert.Equal(new Guid("883F50C5-F554-4C49-98EA-F7CACB41658C"), customer.Title);
            }
            else
            {
                // entity references call
                int id = 81;
                foreach (IEdmEntityObject edmObj in results)
                {
                    EdmEntityObject entity = edmObj as EdmEntityObject;
                    Assert.NotNull(entity);
                    Assert.Equal("NS.Customer", entity.GetEdmType().FullName());

                    dynamic customer = entity;
                    Assert.Equal(id++, customer.Id);
                    Assert.Equal("Id", String.Join(",", customer.GetChangedPropertyNames()));
                    Assert.Equal("Name,Location", String.Join(",", customer.GetUnchangedPropertyNames()));
                }
            }

            return(true);
        }
        public void SendAsync_WritesETagToResponseHeaders_InUntyped()
        {
            // Arrange
            IEdmModel model = GetUnTypeEdmModel();
            HttpRequestMessage request = SetupRequest(HttpMethod.Get, "Customers(3)", model);

            IEdmEntityType entityType = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Customer");
            EdmEntityObject customer = new EdmEntityObject(entityType);
            customer.TrySetPropertyValue("ID", 3);
            customer.TrySetPropertyValue("Name", "Sam");

            HttpResponseMessage originalResponse = SetupResponse(HttpStatusCode.OK, typeof(EdmEntityObject), customer);
            ETagMessageHandler handler = new ETagMessageHandler() { InnerHandler = new TestHandler(originalResponse) };

            // Act
            HttpResponseMessage response = handler.SendAsync(request).Result;

            // Assert
            Assert.NotNull(response.Headers.ETag);
            Assert.Equal("\"J1NhbSc=\"", response.Headers.ETag.Tag);
        }
 public object GetProperty(string property, EdmEntityObject entity)
 {
     return(_dataSource.GetProperty(property, entity));
 }
Esempio n. 32
0
        /// <summary>
        /// Handles a PUT request to fully update an entity.
        /// </summary>
        /// <param name="edmEntityObject">The entity object to update.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The task object that contains the updated result.</returns>
#pragma warning disable CA1062 // Validate public arguments
        public async Task <IActionResult> Put(EdmEntityObject edmEntityObject, CancellationToken cancellationToken)
        => await Update(edmEntityObject, true, cancellationToken).ConfigureAwait(false);