从实体框架核心中的实体获取DbContext

时间:2017-01-27 11:51:48

标签: c# entity-framework reflection entity-framework-core

有没有办法获取DbContext的实例正在跟踪实体(如果有的话)?

我找到了以下EF6的建议/解决方案 Get DbContext from Entity in Entity Framework

do-while

有没有办法在EF Core中获得此结果?

3 个答案:

答案 0 :(得分:1)

没有。 EF Core还没有延迟加载。如果有,那么从它生成的代理最终会引用加载它的DbContext。截至目前,还没有这样的参考。

答案 1 :(得分:0)

没有好办法做到这一点。在构造实体对象之后但在通过调用代码枚举之前,似乎没有简单的方法将任何代码注入到进程中。

Subclassing InternalDbSet是我考虑过的,但你只能修复对.Find方法的调用,而IQueryable实现(你使用DbSet的主要方式)是遥不可及的。

所以我唯一能看到的选项就是不允许访问DbSet,但是具有访问器功能,它将为我设置.Owner(或任何你想要调用的)属性。这很麻烦,因为你通常必须为你想要的每个查询类型编写一个函数,并且调用者不能再使用LINQ了。但是我们可以使用泛型和回调来保持大部分的灵活性,尽管它看起来很难看。这就是我想出来的。

我正在进行移植和清理复杂系统的工作,所以我还没有真正测试这个,但这个概念是合理的。代码可能需要进一步调整才能按需工作。这不应该有任何惩罚,例如,只要你使用EnumerateEntities枚举而不是QueryEntities,在处理任何记录之前拉下整个表,但我还没有对此进行任何真正的测试。

    private void InitEntity(Entity entity) {
        if (entity == null) {
            return;
        }
        entity.Owner = this;
        // Anything you want to happen goes here!
    }
    private DbSet<Entity> Entities { get; set; }
    public IEnumerable<Entity> EnumerateEntities() {
        foreach (Entity entity in this.Entities) {
            this.InitEntity(entity);
            yield return entity;
        }
    }
    public IEnumerable<Entity> EnumerateEntities(Func<DbSet<Entity>, IEnumerable<Entity>> filter) {
        IEnumerable<Entity> ret = filter(this.Entities);
        foreach (Entity entity in ret) {
            this.InitEntity(entity);
            yield return entity;
        }
    }
    public T QueryEntities<T>(Func<DbSet<Entity>, T> filter) {
        if (filter is Func<DbSet<Entity>, Entity>) {
            T ret = filter(this.Entities);
            this.InitEntity(ret as Entity);
            return ret;
        }

        if (filter is Func<DbSet<Entity>, IEnumerable<Entity>>) {
            IEnumerable<Entity> ret = filter(this.Entities) as IEnumerable<Entity>;
            // You should be using EnumerateEntities, this will prefetch all results!!! Can't be avoided, we can't mix yield and no yield in the same function.
            return (T)ret.Select(x => {
                this.InitEntity(x);
                return x;
            });
        }

        return filter(this.Entities);
    }
    public void QueryEntities(Action<DbSet<Entity>> filter) => filter(this.Entities);

答案 2 :(得分:0)

创建时可以在实例/实体上使用依赖项注入。为了允许稍后从实体中检索拥有的dbcontext。

例如

class Book
{
  public readonly DBContext _dbcontext;

  public Book(DBContext dbcontext)
  {
    _dbcontext = dbcontext;
  }

}