Beispiel #1
0
        /// <summary>
        /// 관계 정보를 모두 불러와서 활성화 시키기. 지우기용.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="seen"></param>
        public static void ActivateRelation4Cascade <T>(this T source, HashSet <object> seen) where T : IDbModel
        {
            if (source == null)
            {
                logger.Debug(string.Format("ActivateRelation Source is null : type={0}",
                                           typeof(T).FullName));
                return;
            }
            if (seen.Contains(source) == true)
            {
                return;
            }
            else
            {
                seen.Add(source);
            }

            var props = source.GetType().GetProperties().Where(p => p.GetCustomAttributes(typeof(CascadeRelationAttribute), true).Length != 0 ||
                                                               p.GetCustomAttributes(typeof(CascadeRelationAttribute)).Count() != 0);

            foreach (var prop in props)
            {
                CascadeRelationAttribute attr = (CascadeRelationAttribute)prop.GetCustomAttribute(typeof(CascadeRelationAttribute));
                if (attr.Direction == CascadeRelationAttribute.CascadeDirection.Down)
                {
                    if (typeof(IDbModel).IsAssignableFrom(prop.PropertyType))
                    {
                        var t = prop.GetValue(source, null);
                        ((IDbModel)t).ActivateRelation4Cascade(seen);
                    }
                    else if (typeof(ICollection <>).IsAssignableFrom(prop.PropertyType.GetGenericTypeDefinition()))
                    {
                        var t = (IEnumerable)prop.GetValue(source, null);
                        if (t != null)
                        {
                            foreach (var item in t)
                            {
                                if (typeof(IDbModel).IsAssignableFrom(item.GetType()))
                                {
                                    ((IDbModel)item).ActivateRelation4Cascade(seen);
                                }
                                else
                                {
                                    logger.Debug(string.Format("ActivateRelation Property ICollection<T> T not IDbModel type={0}, ToString={1}",
                                                               item.GetType().FullName,
                                                               item.GetType().ToString()));
                                }
                            }
                        }
                    }
                    else
                    {
                        logger.Debug(string.Format("ActivateRelation Property not IDbModel type={0}, ToString={1}",
                                                   prop.PropertyType.FullName,
                                                   prop.PropertyType.ToString()));
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Deep 복사 본 만들기. DB 저장을 위해 관계 처리
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="source"></param>
        /// <param name="seen"></param>
        /// <param name="bCopykey"></param>
        /// <param name="bCascade"></param>
        /// <param name="direction"></param>
        /// <param name="bClone"></param>
        /// <returns></returns>
        public static TEntity Clone <TEntity>(this TEntity source, Dictionary <object, object> seen, bool bCopykey, bool bCascade, CascadeRelationAttribute.CascadeDirection direction, bool bClone)
            where TEntity : IKeyModel
        {
            if (source == null)
            {
                logger.Debug(string.Format("Clone Source is null return default(T): type={0}",
                                           typeof(TEntity).FullName));
                return(default(TEntity));
            }
            if (seen.ContainsKey(source) == true)
            {
                return((TEntity)seen[source]);
            }

            //부모자식 관계 일 때는 자식이 부모를 만들지 않고 원본을 그대로 돌려주도록 해야 함
            if (direction == CascadeRelationAttribute.CascadeDirection.Up || bClone == false)
            {
                logger.Debug(string.Format("Clone Source as it is : type={0}, id={1}",
                                           source.GetType().FullName, source.ToString()));
                seen.Add(source, source);
                return(source);
            }


            TEntity clone = (TEntity)Activator.CreateInstance(source.GetType());

            seen.Add(source, clone);

            //NonCopyable 하지 않고, CascadeRelation에 속하지 않은 프로퍼티 모두 복사
            var props = source.GetType().GetProperties().Where(p => p.GetCustomAttributes(typeof(NonCopyableAttribute), true).Length == 0 &&
                                                               p.GetCustomAttributes(typeof(NonCopyableAttribute)).Count() == 0 &&
                                                               p.GetCustomAttributes(typeof(CascadeRelationAttribute), true).Length == 0 &&
                                                               p.GetCustomAttributes(typeof(CascadeRelationAttribute)).Count() == 0);

            var keyName = source.GetKeyName();  //Key의 이름은 동적으로 받아서 사용.

            foreach (var prop in props)
            {
                if (prop.Name == keyName)
                {
                    if (bCopykey == false)
                    {
                        continue;
                    }
                }
                prop.SetValue(clone, prop.GetValue(source, null), null);
            }

            //CascadeRelation에 속한 프로퍼티는 Cascade 복사
            if (bCascade == true)
            {
                props = source.GetType().GetProperties().Where(p => (p.GetCustomAttributes(typeof(CascadeRelationAttribute), true).Length != 0 ||
                                                                     p.GetCustomAttributes(typeof(CascadeRelationAttribute)).Count() != 0) &&
                                                               p.GetCustomAttributes(typeof(NonCopyableAttribute), true).Length == 0 &&
                                                               p.GetCustomAttributes(typeof(NonCopyableAttribute)).Count() == 0);

                foreach (var prop in props)
                {
                    if (typeof(IKeyModel).IsAssignableFrom(prop.PropertyType))
                    {
                        var t = (IKeyModel)prop.GetValue(source, null);

                        CascadeRelationAttribute attr = (CascadeRelationAttribute)prop.GetCustomAttribute(typeof(CascadeRelationAttribute));
                        prop.SetValue(clone, t == null ? null : t.Clone(seen, bCopykey, bCascade, attr.Direction, attr.Clonable), null);
                    }
                    else if (prop.PropertyType.IsGenericType && typeof(ICollection <>).IsAssignableFrom(prop.PropertyType.GetGenericTypeDefinition()))
                    {
                        var listType            = typeof(List <>);
                        var constructedListType = listType.MakeGenericType(prop.PropertyType.GetGenericArguments()[0]);
                        var instance            = (IList)Activator.CreateInstance(constructedListType);

                        var t = (IEnumerable)prop.GetValue(source, null);
                        if (t != null)
                        {
                            foreach (var item in t)
                            {
                                if (typeof(IKeyModel).IsAssignableFrom(item.GetType()))
                                {
                                    CascadeRelationAttribute attr = (CascadeRelationAttribute)prop.GetCustomAttribute(typeof(CascadeRelationAttribute));
                                    instance.Add(item == null ? null : ((IKeyModel)item).Clone(seen, bCopykey, bCascade, attr.Direction, attr.Clonable));
                                }
                                else
                                {
                                    logger.Debug(string.Format("Clone Property ICollection<T> T not IKeyModel type={0}, ToString={1}",
                                                               item.GetType().FullName,
                                                               item.GetType().ToString()));
                                }
                            }
                        }
                        prop.SetValue(clone, instance, null);
                    }
                    else
                    {
                        logger.Debug(string.Format("Clone Property not IKeyModel type={0}, ToString={1}",
                                                   prop.PropertyType.FullName,
                                                   prop.PropertyType.ToString()));
                    }
                }
            }

            return(clone);
        }