实体框架 - 关联实体 - 关联导航属性?

3
我有以下通用代码来更新一个断开连接的实体:
```csharp public void Update(TEntity entityToUpdate) where TEntity : class { context.Set().Attach(entityToUpdate); context.Entry(entityToUpdate).State = EntityState.Modified; } ```
该方法使用泛型来接收任何类型的实体,并使用 Entity Framework 的上下文对象将其附加到数据库中。然后,它将实体状态设置为修改,以便在保存更改时将其更新到数据库中。
public T UpdateItem(T entity)
{
    this._dbSet.Attach(entity);
    this._dbContext.Entry(entity).State = System.Data.EntityState.Modified;

    this._dbContext.SaveChanges();

    return entity;
}

如果我的实体包含导航属性,这些属性不会被附加并设置为修改状态。有没有办法改变这个通用方法,将所有导航属性都附加并设置为修改状态?
1个回答

6
你可以使用反射来实现。这里有一个查找所有相关集合的扩展方法。如果你的所有实体都实现了某个标准接口,那么你就能够编写一个类似的方法来查找非集合导航属性(实现你的接口)。
public static class ContextExtensions
{
    public static IEnumerable<IEnumerable<dynamic>> GetCollections(this object o)
    {
        var result = new List<IEnumerable<dynamic>>();
        foreach (var prop in o.GetType().GetProperties())
        {
            if (typeof(IEnumerable<dynamic>).IsAssignableFrom(prop.PropertyType))
            {
                var get = prop.GetGetMethod();
                if (!get.IsStatic && get.GetParameters().Length == 0)
                {
                    var enumerable = (IEnumerable<dynamic>)get.Invoke(o, null);
                    if (enumerable != null) result.Add(enumerable);
                }
            }
        }
        return result;
    }
}

这应该添加当前对象的导航属性。

var collections = entity.GetCollections();
foreach (var collection in collections)
{
    foreach (var r in collection)
    {
        if (_this._dbSet.Entry(r).State == System.Data.EntityState.Detached)
        {
            this._dbSet.Attach(r);
            this._dbContext.Entry(r).State = System.Data.EntityState.Modified;
        }
    }
}

我很少使用 dynamic,但有点惊讶于 typeof(IEnumerable<dynamic>).IsAssignableFrom 是有效的。这是否基本上解析为 IEnumerable<object> 或者在评估过程中它会自动用 prop.PropertyType 替换 dynamic - xr280xr
GetCollections 返回嵌套的可枚举对象,这是我没有看到的原因吗? - CervEd
我猜只需返回集合而不是集合中的实体,尽管在这种情况下,只返回所有要附加的实体的集合就足够了。 - CervEd
@CervEd 这个例子返回一个集合的集合(即一个列表的列表)- 例如一个人可以有一个孩子列表和一个朋友列表,这个方法将有效地返回由这两个集合组成的一个集合。 - qujck
@qujck 的确如此,但在这个例子中,我想知道是否有理由这样做。我想知道它是否只会导致不必要的迭代。 - CervEd
@CervEd 答案的第二部分取决于集合的集合和工作。 - qujck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接