You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#含深层嵌套与循环引用的数据库实体克隆方案咨询

支持循环引用的多层数据库实体克隆方案咨询

我有一个嵌套层级达8层的数据库实体,尝试使用带ReferenceHandler选项的System.Text.Json.Serializer,以及带ReferenceHandler.Ignore选项的JsonConvert.SerializeObject进行克隆,但均无响应(最长等待10分钟未返回)。现咨询是否有更优的支持循环引用的数据库实体克隆方案?

更新

我已基于C#反射技术实现了递归克隆功能,可处理循环引用并跳过无需克隆的实体(如我的场景中的参考表),能在微秒/秒级完成N层实体克隆,但该实现仍有优化精简空间,代码如下:

public object Clone(string[] skipEntites, Type circularType = null)
{
    var newEntity = Activator.CreateInstance(this.GetType());

    PropertyInfo[] entityProperties = newEntity.GetType().GetProperties();

    foreach (PropertyInfo entityProperty in entityProperties)
    {
        var value = this.GetType().GetProperty(entityProperty.Name).GetValue(this);

        if (TryGetArgumentTypesFromHashSet(value, out Type[] argumentTypes))
        {
            if (circularType != null && circularType.Name.Contains(argumentTypes[0].Name))
            {
                continue;
            }

            Type hashSetType = typeof(HashSet<>).MakeGenericType(argumentTypes[0]);
            var hashSet = Activator.CreateInstance(hashSetType);
            MethodInfo addMethod = hashSetType.GetMethod("Add");

            var entities = (IEnumerable)value;
            foreach (IEntity entity in entities)
            {
                addMethod.Invoke(hashSet, new object[] { entity.Clone(skipEntites, GetType()) });
            }

            SetValue(entityProperty, hashSet, newEntity, skipEntites);
            continue;
        }

        if (value != null && circularType != null && circularType.Name.Contains(value.GetType().Name))
        {
            continue;
        }

        if (circularType != null
            && circularType.Name.Contains(entityProperty.Name.Substring(0, entityProperty.Name.Length-2))
            && entityProperty.Name.Contains("Id")
            && (entityProperty.PropertyType == typeof(int)
               || entityProperty.PropertyType == typeof(long)
               || entityProperty.PropertyType == typeof(int?)
               || entityProperty.PropertyType == typeof(long?))
            )
        {
            entityProperty.SetValue(newEntity, 0);
            continue;
        }

        SetValue(entityProperty, value, newEntity, skipEntites);
    }

    return newEntity;
}

private bool TryGetArgumentTypesFromHashSet(object value, out Type[] argumentTypes)
{
    argumentTypes = null;

    if (value == null)
    {
        return false;
    }

    Type type = value.GetType();
    argumentTypes = type.GetGenericArguments();

    return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>) && argumentTypes.Length > 0;
}

private void SetValue(PropertyInfo entityProperty, object value, object newEntity, string[] skipEntites)
{
    if (value != null && skipEntites.Any(x => value.GetType().Name.Contains(x)))
    {
        return;
    }

    if (value is IEntity referenceObject)
    {
        var newReference = referenceObject.Clone(skipEntites, GetType());

        entityProperty.SetValue(newEntity, newReference);
        return;
    }

    if (entityProperty.Name == "Id" && (entityProperty.PropertyType == typeof(int) || entityProperty.PropertyType == typeof(long)))
    {
        entityProperty.SetValue(newEntity, 0);
        return;
    }

    entityProperty.SetValue(newEntity, value);
}

内容的提问来源于stack exchange,提问作者ARr0w

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:21:00