Example #1
0
        /// <summary>
        /// Handle $expand
        /// </summary>
        /// <param name="entry">Entry</param>
        /// <param name="edmParent">Parent EntitySet</param>
        /// <param name="targetVersion">Target Version</param>
        /// <param name="expandedNavigationItems">Expand Items</param>
        /// <param name="parentId">Parent Id</param>
        private void GenerateDeltaItemsFromExpand(object entry, IEdmNavigationSource edmParent, ODataVersion targetVersion, IEnumerable <ExpandedNavigationSelectItem> expandedNavigationItems, string parentId)
        {
            foreach (var navigationProperty in ((IEdmEntityType)EdmClrTypeUtils.GetEdmType(this.DataSource.Model, entry)).NavigationProperties())
            {
                var expandedNavigationItem = GetExpandedNavigationItem(expandedNavigationItems, navigationProperty.Name);

                if (expandedNavigationItem != null)
                {
                    bool isCollection = navigationProperty.Type.IsCollection();

                    ExpandSelectItemHandler expandItemHandler = new ExpandSelectItemHandler(entry);
                    expandedNavigationItem.HandleWith(expandItemHandler);
                    var propertyValue = expandItemHandler.ExpandedChildElement;

                    if (propertyValue != null)
                    {
                        IEdmNavigationSource targetSource = edmParent.FindNavigationTarget(navigationProperty);

                        if (isCollection)
                        {
                            var expandedEntities = propertyValue as IEnumerable;
                            foreach (var expandedEntity in expandedEntities)
                            {
                                GenerateDeltaItemFromEntry(expandedEntity, targetSource, targetVersion, expandedNavigationItem.SelectAndExpand, parentId, navigationProperty.Name);
                            }
                        }
                        else
                        {
                            GenerateDeltaItemFromEntry(propertyValue, targetSource, targetVersion, expandedNavigationItem.SelectAndExpand, parentId, navigationProperty.Name);
                        }
                    }

                    // Handle deleted entry and link here
                    GenerateDeltaItemsFromDeletedEntities(parentId, navigationProperty.Name);
                }
            }
        }
        private static void UpdateCore(object target, string propertyName, object propertyValue)
        {
            var odataComplexValue    = propertyValue as ODataComplexValue;
            var odataCollectionValue = propertyValue as ODataCollectionValue;
            var odataEnumValue       = propertyValue as ODataEnumValue;
            var odataPrimitiveValue  = propertyValue as ODataPrimitiveValue;

            if (odataComplexValue != null)
            {
                var property = target.GetType().GetProperty(propertyName);
                if (property != null)
                {
                    var value = property.GetValue(target, null);
                    if (value == null)
                    {
                        var valueType    = EdmClrTypeUtils.GetInstanceType(odataComplexValue.TypeName);
                        var propertyType = property.PropertyType;
                        if (valueType.IsSubclassOf(propertyType) || valueType == propertyType)
                        {
                            value = Utility.QuickCreateInstance(valueType);
                        }
                        else
                        {
                            throw new InvalidOperationException(string.Format("{0} is not equal or derived from {1}", valueType, propertyType));
                        }

                        property.SetValue(target, value, null);
                    }

                    foreach (var p in odataComplexValue.Properties)
                    {
                        UpdateCore(value, p.Name, p.Value);
                    }

                    return;
                }
            }
            else if (odataCollectionValue != null)
            {
                var property = target.GetType().GetProperty(propertyName);
                if (property != null)
                {
                    var collection = Utility.QuickCreateInstance(property.PropertyType);

                    foreach (var item in odataCollectionValue.Items)
                    {
                        var itemType = property.PropertyType.GetGenericArguments().Single();
                        odataComplexValue    = item as ODataComplexValue;
                        odataCollectionValue = item as ODataCollectionValue;
                        object collectionItem = null;
                        if (odataComplexValue != null)
                        {
                            // TODO: call Create method to new instance instead
                            collectionItem = Utility.QuickCreateInstance(itemType);
                            foreach (var p in odataComplexValue.Properties)
                            {
                                UpdateCore(collectionItem, p.Name, p.Value);
                            }
                        }
                        else if (odataCollectionValue != null)
                        {
                            // TODO, check should support this type or not
                            throw new NotImplementedException();
                        }
                        else
                        {
                            collectionItem = ODataObjectModelConverter.ConvertPropertyValue(item, itemType);
                        }

                        property.PropertyType.GetMethod("Add").Invoke(collection, new object[] { collectionItem });
                    }

                    property.SetValue(target, collection, null);

                    return;
                }
            }
            else
            {
                var property = target.GetType().GetProperty(propertyName);
                if (property != null)
                {
                    property.SetValue(target, ODataObjectModelConverter.ConvertPropertyValue(propertyValue, property.PropertyType), null);
                    return;
                }
            }

            var openClrObject = target as OpenClrObject;

            if (openClrObject != null)
            {
                var structuredType = (IEdmStructuredType)EdmClrTypeUtils.GetEdmType(DataSourceManager.GetCurrentDataSource().Model, openClrObject);

                //check if the edmType is an open type
                if (structuredType.IsOpen)
                {
                    if (odataCollectionValue != null)
                    {
                        // Collection of Edm.String
                        if (odataCollectionValue.TypeName == "Collection(Edm.String)")
                        {
                            var collection = new Collection <string>();
                            foreach (var it in odataCollectionValue.Items)
                            {
                                collection.Add(it as string);
                            }
                            openClrObject.OpenProperties[propertyName] = collection;
                        }
                        else
                        {
                            // TODO: handle other types.
                            throw new NotImplementedException();
                        }
                    }
                    else if (odataComplexValue != null)
                    {
                        var type  = EdmClrTypeUtils.GetInstanceType(odataComplexValue.TypeName);
                        var value = Utility.QuickCreateInstance(type);
                        foreach (var property in odataComplexValue.Properties)
                        {
                            UpdateCore(value, property.Name, property.Value);
                        }
                        openClrObject.OpenProperties[propertyName] = value;
                    }
                    else if (odataEnumValue != null)
                    {
                        var type = EdmClrTypeUtils.GetInstanceType(odataEnumValue.TypeName);
                        openClrObject.OpenProperties[propertyName] = ODataObjectModelConverter.ConvertPropertyValue(propertyValue, type);
                    }
                    else if (odataPrimitiveValue != null)
                    {
                        openClrObject.OpenProperties[propertyName] = odataPrimitiveValue.Value;
                    }
                    else
                    {
                        openClrObject.OpenProperties[propertyName] = propertyValue;
                    }
                }
            }
        }