Ejemplo n.º 1
0
        /// <summary>
        /// Base implementation to save an instance hierarchy.
        /// </summary>
        /// <param name="uow">An open unit of work</param>
        /// <param name="productInstance">The instance to save</param>
        /// <returns>The instance entity.</returns>
        private ProductInstanceEntity SaveInstance(IUnitOfWork uow, ProductInstance productInstance)
        {
            // Check if this type is persisted
            var strategy = InstanceStrategies[productInstance.GetType().Name];

            if (strategy.SkipInstances)
            {
                return(null);
            }

            // Save to entity
            var archived = uow.GetEntity <ProductInstanceEntity>(productInstance);

            archived.ProductId = productInstance.Type.Id;
            strategy.SaveInstance(productInstance, archived);

            // Save its parts if the have a dedicated archive
            var partsContainer = ReflectionTool.GetReferences <ProductInstance>(productInstance);

            foreach (var partGroup in partsContainer)
            {
                foreach (var part in partGroup)
                {
                    var partEntity = SaveInstance(uow, part);
                    if (partEntity == null) // Parts are null when they are skipped
                    {
                        continue;
                    }

                    partEntity.Parent     = archived;
                    partEntity.PartLinkId = part.PartLink.Id;
                }
            }

            return(archived);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Recursive function to transform entities into objects
        /// </summary>
        private void TransformInstance(IUnitOfWork uow, ProductInstanceEntity entity, ProductInstance productInstance)
        {
            // Transform the instance if it has a dedicated storage
            var product = productInstance.Type;

            // Check if instances of this type are persisted
            var strategy = InstanceStrategies[productInstance.GetType().Name];

            if (strategy.SkipInstances)
            {
                return;
            }

            // Transfrom entity to instance
            strategy.LoadInstance(entity, productInstance);

            // Group all parts of the instance by the property they belong to
            var partLinks = ReflectionTool.GetReferences <IProductPartLink>(product)
                            .SelectMany(g => g).ToList();
            var partGroups = ReflectionTool.GetReferences <ProductInstance>(productInstance)
                             .ToDictionary(p => p.Key, p => p.ToList());
            var partEntityGroups = entity.Parts.GroupBy(p => p.PartLink.PropertyName)
                                   .ToDictionary(p => p.Key, p => p.ToList());

            // Load and populate parts
            foreach (var partGroup in partGroups)
            {
                var linkStrategy = LinkStrategies[product.GetType().Name][partGroup.Key.Name];
                if (linkStrategy.PartCreation == PartSourceStrategy.FromPartlink && partEntityGroups.ContainsKey(partGroup.Key.Name))
                {
                    // Update all parts that are also present as entities
                    foreach (var partEntity in partEntityGroups[partGroup.Key.Name])
                    {
                        var part = partGroup.Value.First(p => p.PartLink.Id == partEntity.PartLinkId);
                        TransformInstance(uow, partEntity, part);
                    }
                }
                else if (linkStrategy.PartCreation == PartSourceStrategy.FromEntities)
                {
                    // Load part using the entity and assign PartLink afterwards
                    var partCollection = partEntityGroups[partGroup.Key.Name].ToList();
                    var partArticles   = TransformArticles(uow, partCollection);
                    for (var index = 0; index < partArticles.Length; index++)
                    {
                        partArticles[index].PartLink = partLinks.Find(pl => pl?.Id == partCollection[index].PartLinkId.Value);
                    }

                    if (typeof(ProductInstance).IsAssignableFrom(partGroup.Key.PropertyType) && partArticles.Length == 0)
                    {
                        partGroup.Key.SetValue(productInstance, partArticles[0]);
                    }
                    else
                    {
                        var elementType = partGroup.Key.PropertyType.GetGenericArguments()[0];
                        var listType    = typeof(List <>).MakeGenericType(elementType);
                        var list        = (IList)Activator.CreateInstance(listType);
                        foreach (var partArticle in partArticles)
                        {
                            list.Add(partArticle);
                        }
                    }
                }
            }
        }