在 EF core 中,在一个类中添加实体后,如何在不调用 SaveChanges() 的情况下从另一个类访问实体?



我有一个中等复杂的创建操作,在我正在处理的系统中被分解为多个部分。假设 3 个类:

  • 操作编排器
  • 实体创建者
  • 实体修饰符

使用通过 DI 共享的数据库上下文实例(上下文的范围按请求确定(,业务流程协调程序将调用Creator修饰符来构建复杂的对象和一系列关系,然后再最终提交该操作。

我的问题是,当实体修饰符尝试访问通过实体创建创建的实体时,我遇到了"序列不包含任何元素"异常。一些伪代码来说明:

public class OperationOrchestrator
{
private IContext _context;
private IEntityCreator _entityCreator, 
private IEntityModifier _entityModifier
public OperationOrchestrator(
IContext context, 
IEntityCreator entityCreator, 
IEntityModifier entityModifier
)
{
//boilerplate var assignment code
}
public void CreatePerson(string name, int age)
{
var id = _entityCreator.CreatePerson(name);
_entityModifier.UpdatePersonAge(id, age);
_context.SaveChanges();
}
}
public class EntityCreator : IEntityCreator 
{
private IContext _context;
public EntityCreator (
IContext context
)
{
_context = context;
}
public Guid CreatePerson(string name)
{
var person = new Person {
Id = Guid.NewGuid(),
Name = name
};
_context.Add(person);
return person.Id;
}
}
public class EntityModifier : IEntityModifier
{
private IContext _context;
public EntityModifier (
IContext context
)
{
_context = context;
}
public void UpdatePersonAge(Guid id, int age)
{
var person = _context.People.Single(x => x.Id == id);
person.Age = age;
}
}

这里的问题电话在context.People.Single(x => x.Id == id);.上下文似乎尚未将新人员添加到其人员数据库集中,即使上下文的实例在类之间应该是相同的。最重要的是,如果我调试并检查局部变量,我可以在上下文的 ChangeTracker 中看到新创建的人。

最后,如果我在UpdatePersonAge()方法中调用SaveChanges(),就在调用context.People.Single(x => x.Id == id);之前,立即检索人员的尝试将成功。

这是针对实体框架的预期设计,还是可以设置某些配置选项来替代此行为?

提前感谢!

这是根据 DbSet 的摘要进行设计的:

针对 DbSet{TEntity} 的 LINQ 查询的结果将包含以下结果 从数据库返回,并且可能不会反映在上下文中所做的更改,这些更改尚未 已保存到数据库。例如,结果将不包含新添加的实体 并且可能仍包含标记为删除的实体。

您可以先在更改跟踪器中检查实体,然后如果在哪里没有,则可以转到数据库。这也将减少应用程序将生成的查询量。

public class EntityModifier : IEntityModifier
{
private IContext _context;
public EntityModifier(IContext context)
{
_context = context;
}
public void UpdatePersonAge(Guid id, int age)
{
var person = _context.ChangeTracker.Entries<Person>().SingleOrDefault(x => x.Id == id) ??
_context.People.Single(x => x.Id == id);
person.Age = age;
}
}

最新更新