我有一个中等复杂的创建操作,在我正在处理的系统中被分解为多个部分。假设 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;
}
}