在实际更新Mongo对象时发现,原有的更新代码无法更新复杂的数据类型对象。恰好看到张占岭老师有对该方法做相关的改进,因此全抄了下来。

总的核心思想就是运用反射递归,对对象属性一层一层挖掘下去,循环创建父类及之类的更新表达式。

相关代码如下:

#region 递归获取字段更新表达式

private List<UpdateDefinition<T>> GetUpdateDefinitions<T>(T entity)
{
    var type = typeof(T);
    var fieldList = new List<UpdateDefinition<T>>();

    foreach (var property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public))
    {
        GenerateRecursion<T>(fieldList, property, property.GetValue(entity), entity, "");
    }

    return fieldList;
}

private void GenerateRecursion<TEntity>(
      List<UpdateDefinition<TEntity>> fieldList,
      PropertyInfo property,
      object propertyValue,
      TEntity item,
      string father)
{
    //复杂类型
    if (property.PropertyType.IsClass && property.PropertyType != typeof(string) && propertyValue != null)
    {
        //集合
        if (typeof(IList).IsAssignableFrom(propertyValue.GetType()))
        {
            foreach (var sub in property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                if (sub.PropertyType.IsClass && sub.PropertyType != typeof(string))
                {
                    var arr = propertyValue as IList;
                    if (arr != null && arr.Count > 0)
                    {
                        for (int index = 0; index < arr.Count; index++)
                        {
                            foreach (var subInner in sub.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
                            {
                                if (string.IsNullOrWhiteSpace(father))
                                    GenerateRecursion(fieldList, subInner, subInner.GetValue(arr[index]), item, property.Name + "." + index);
                                else
                                    GenerateRecursion(fieldList, subInner, subInner.GetValue(arr[index]), item, father + "." + property.Name + "." + index);
                            }
                        }
                    }
                }
            }
        }
        //实体
        else
        {
            foreach (var sub in property.PropertyType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {

                if (string.IsNullOrWhiteSpace(father))
                    GenerateRecursion(fieldList, sub, sub.GetValue(propertyValue), item, property.Name);
                else
                    GenerateRecursion(fieldList, sub, sub.GetValue(propertyValue), item, father + "." + property.Name);
            }
        }
    }
    //简单类型
    else
    {
        if (property.Name != "_id")//更新集中不能有实体键_id
        {
            if (string.IsNullOrWhiteSpace(father))
                fieldList.Add(Builders<TEntity>.Update.Set(property.Name, propertyValue));
            else
                fieldList.Add(Builders<TEntity>.Update.Set(father + "." + property.Name, propertyValue));
        }
    }
}

/// <summary>
/// 构建Mongo的更新表达式
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
private List<UpdateDefinition<T>> GeneratorMongoUpdate<T>(T item)
{
    var fieldList = new List<UpdateDefinition<T>>();
    foreach (var property in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public))
    {
        GenerateRecursion<T>(fieldList, property, property.GetValue(item), item, string.Empty);
    }
    return fieldList;
}

#endregion
View Code

相关文章:

  • 2022-12-23
  • 2021-07-19
  • 2021-06-09
  • 2021-05-28
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-05-05
  • 2021-12-21
相关资源
相似解决方案