Example #1
0
        private static TTo CopyTo <TFrom, TTo>(this IEntityGraphShape shape, TFrom fromEntity, ITypeMapper typeMapper, IList visited)
            where TFrom : class
            where TTo : class
        {
            var toEntity = CopyFromTo <TFrom, TTo>(fromEntity, typeMapper);

            Debug.Assert(visited.Contains(fromEntity) == false);
            visited.Add(fromEntity);

            // Determine if provided shape is defined for fromEntity or for toEntity.
            var outEdges = shape.OutEdges(fromEntity).ToList();

            if (!outEdges.Any())
            {
                outEdges = shape.OutEdges(toEntity).ToList();
            }
            var fromType = fromEntity.GetType();
            var toType   = toEntity.GetType();

            foreach (var edge in outEdges)
            {
                var fromPropInfo = fromType.GetProperty(edge.Name);
                var toPropInfo   = toType.GetProperty(edge.Name);
                if (fromPropInfo == null || toPropInfo == null)
                {
                    continue;
                }
                var fromPropvalue = fromPropInfo.GetValue(fromEntity, null);
                if (fromPropvalue == null)
                {
                    continue;
                }
                if (typeof(IEnumerable).IsAssignableFrom(fromPropInfo.PropertyType))
                {
                    var fromChildren = (IEnumerable)fromPropvalue;

                    var toList = (IEnumerable)toPropInfo.GetValue(toEntity, null);
                    // If the IEnumerable is null, lets try to allocate one
                    if (toList == null)
                    {
                        var constr = toPropInfo.PropertyType.GetConstructor(new Type[] {});
                        toList = (IEnumerable)constr.Invoke(new object[] {});
                        toPropInfo.SetValue(toEntity, toList, null);
                    }
                    var addMethod = toPropInfo.PropertyType.GetMethod("Add");
                    foreach (var fromChild in fromChildren)
                    {
                        if (visited.Contains(fromChild) == false)
                        {
                            var toChild = shape.CopyTo <TFrom, TTo>((TFrom)fromChild, typeMapper, visited);
                            addMethod.Invoke(toList, new object[] { toChild });
                        }
                    }
                }
                else
                {
                    var fromChild = (TFrom)fromPropvalue;
                    if (visited.Contains(fromChild) == false)
                    {
                        var toChild = shape.CopyTo <TFrom, TTo>(fromChild, typeMapper, visited);
                        toPropInfo.SetValue(toEntity, toChild, null);
                    }
                }
            }
            return(toEntity);
        }