【问题标题】:Generic method to traverses Entity Framework parent child relationships遍历实体框架父子关系的通用方法
【发布时间】:2019-12-11 02:06:16
【问题描述】:

我正在尝试在我的实体框架存储库的基类中编写一个通用方法,它将记录和相关的子记录标记为已删除。本质上与 EF 级联删除功能相同,但更新每个记录上的属性而不是删除它。

在我的模型中,我有一个名为“已删除”的布尔属性以及 ICollection 类型的各种导航属性。我在名为 MarkDeleted 的基础存储库中创建了通用方法,它将单个实体作为通用类型参数。

我的计划是遍历实体的所有属性,如果它是“已删除”属性,则将其设置为“true”,如果它是集合属性,则遍历调用相同 MarkDeleted 方法的集合的所有实体将当前实体作为参数传递。

我已经设置了 Deleted 标志并通过查看诸如 How would I know if a property is a generic collection 之类的帖子来识别实体的哪些属性是集合属性

我的问题是从集合属性中检索相关实体的集合。

    public int MarkDeleted(T entity)
    {
        foreach (var prop in entity.GetType().GetProperties())
        {
            if (prop.Name == "Deleted")
            {
                prop.SetValue(entity, true);
            }

            if (prop.PropertyType.IsGenericType && 
                typeof(ICollection<>).IsAssignableFrom(prop.PropertyType.GetGenericTypeDefinition()))
            {
                foreach (var child in prop.xxxx ) //This is where I come unstuck. 
                                                  //How do I convert current property to its collection?
                {
                    MarkDeleted(child);
                }
            }
        }
        return SaveChanges();
    }

如果我在运行时检查这个实体参数,我可以看到 EF 已经预先加载了实体中的所有相关集合。所以他们在那里,我只需要弄清楚如何访问它们。

【问题讨论】:

    标签: c# entity-framework recursion reflection


    【解决方案1】:

    要实现这一点,您需要获取该属性并将其转换为可以迭代的东西。更具体地说,您需要将其转换为至少 IEnumerable。这是一个有效的强制转换,因为您已经在检查实现 IEnumerableICollection&lt;&gt;

    if (prop.PropertyType.IsGenericType &&
        typeof(ICollection<>).IsAssignableFrom(prop.PropertyType.GetGenericTypeDefinition()))
    {
        foreach (var child in (prop.GetValue(entity) as IEnumerable)) //Cast it here
        {
            MarkDeleted(child);
        }
    }
    

    【讨论】:

    • 完美,谢谢。我必须进行一项额外的更改,那就是将 MarkDeleted 的签名从 MarkDeleted(T entity) 更改为 MarkDeleted(object entity) 否则我收到错误 Cannot convert from 'object' to T.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多