有没有办法获取DbContext的实例正在跟踪实体(如果有的话)?
我找到了以下EF6的建议/解决方案 Get DbContext from Entity in Entity Framework
do-while
有没有办法在EF Core中获得此结果?
答案 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;
}
}