Пример #1
0
        protected object LoadObject(IObjectGraph source, Dictionary <object, object> parsedObjects)
        {
            if (!source.IsAnonymous)
            {
                var instance = source.GetInstance();
                if (instance is IEntity)
                {
                    instance = GetCopyInContextOrAttach(instance as IEntity);
                }

                LoadIncludes(source, instance, parsedObjects);

                return(instance);
            }

            else
            {
                //Anonymous Types
                var anonType = source.GetInstanceType();
                var ctor     = anonType.GetConstructors().Single();

                var deserializedIncludes = new Dictionary <PropertyInfo, object>();

                foreach (var property in source.GetPropertiesNeedingContextBinding())
                {
                    if (!TypesUtil.IsNonPrimitiveCollection(property.PropertyType))
                    {
                        var propertyValue = LoadObject(source.GetObjectGraphForProperty(property), parsedObjects);
                        deserializedIncludes.Add(property, propertyValue);
                    }
                    else
                    {
                        var collectionItems = source.GetObjectGraphForCollection(property)
                                              .Select(itemInfo => LoadObject(itemInfo, parsedObjects)).ToList();

                        var propertyValue = MakeEnumerable(property.PropertyType, collectionItems);

                        deserializedIncludes.Add(property, propertyValue);
                    }
                }

                var ctorArgs = deserializedIncludes.Select(kvp => kvp.Value).ToArray();

                return(Activator.CreateInstance(anonType, ctorArgs));
            }
        }
Пример #2
0
        protected void LoadIncludes(IObjectGraph source, object instance, Dictionary <object, object> parsedObjects)
        {
            if (parsedObjects.ContainsKey(instance))
            {
                return;
            }

            //Add it to the parsed objects list, so that we can avoid going through circular relationships.
            parsedObjects.Add(instance, null);

            if (source.IsCollection)
            {
                var sourceCollection = source.GetSourceCollection();
                var ctr = 0;
                foreach (var item in (instance as IEnumerable))
                {
                    LoadIncludes(sourceCollection[ctr++], item, parsedObjects);
                }
            }
            else
            {
                foreach (var property in source.GetPropertiesNeedingContextBinding())
                {
                    if (!TypesUtil.IsNonPrimitiveCollection(property.PropertyType))
                    {
                        //If the instance is an Entity, we treat property setting differently.
                        //  This is because setters will automatically trigger Reverse Reference setters.
                        if (instance is IEntity)
                        {
                            var propValFromSource = source.GetPropertyValue(property);
                            var loadedValue       = property.GetValue(instance);

                            //If the property is already loaded in our current instance, we should not touch it.
                            //  Yet, if they (current instance and the source) refer to the same value, we should attach includes.
                            //If they are NOT the same, we do nothing. (Since the user changed the property, can't overwrite.)
                            if (IsPropertyLoadedOnEntity(instance, property))
                            {
                                if (loadedValue != null && loadedValue is IEntity &&
                                    ((IEntity)loadedValue).IsEquivalent((IEntity)propValFromSource))
                                {
                                    LoadIncludes(source.GetObjectGraphForProperty(property), loadedValue, parsedObjects);
                                }
                            }

                            //Property is not loaded on the current instance. Go ahead and add it via Materialization methods.
                            else
                            {
                                if (source.GetPropertyValue(property) != null)
                                {
                                    var propertyValue         = LoadObject(source.GetObjectGraphForProperty(property), parsedObjects);
                                    var intermediateContainer = GetBackingContainerForProperty(instance as IEntity, property);
                                    intermediateContainer.MaterializationAddReference((propertyValue as IEntity)._getIntermediateEntity());
                                }
                            }
                        }

                        //Instance is not an IEntity, we can just set the property value.
                        else
                        {
                            if (source.GetPropertyValue(property) != null)
                            {
                                var propertyValue = LoadObject(source.GetObjectGraphForProperty(property), parsedObjects);
                                property.SetValue(instance, propertyValue);
                            }
                        }
                    }

                    //This property is a collection.
                    else
                    {
                        var entityList = source.GetObjectGraphForCollection(property)
                                         .Select(collItemSource => LoadObject(collItemSource, parsedObjects)).ToList();

                        if (IsManyToMany(property))
                        {
                            //Many-to-Many collection can only exist in Entities, hence the cast.
                            AddToManyToManyCollection((IEntity)instance, property, entityList);
                        }
                        else
                        {
                            SetEnumerableProperty(instance, property, MakeEnumerable(property.PropertyType, entityList));
                        }
                    }
                }
            }
        }