关于EF的dbContext如何工作,我有点困惑。
如果我做_context.Persons.Add(_person)
之类的事情(假设人是一个有效的实体),如果我(在调用_context.SaveChanges()之前)查询人员,我刚添加的人是否会被包含在结果中?< / p>
例如:
Person _person = new Person() {Firstname = "Bill", Lastname = "Snerdly"};
_context.Persons.Add(_person);
var _personList = _context.Persons.Where(p => p.Lastname.StartsWith("Sne"));
每当我尝试这个时,似乎上下文都没有跟踪我将这个新人添加到上下文这一事实。
令我困惑的是,如果我编辑现有人并附加此人并将状态设置为已修改,则查询上下文似乎会跟踪所做的更改并将其返回到结果中。例如:
//Assuming that Person 5 exists with the name William Snerdly
Person _person = new Person() {Id = 5, Firstname = "Bill", Lastname = "Snerdly"};
_context.Persons.Attach(_person);
_context.Entry(_person).State = System.Data.EntityState.Modified;
var _personList = _context.Persons.Where(p => p.Lastname.StartsWith("Sne"));
在这种情况下,似乎id为5的人将在名单中显示名称为Bill而不是William。 IOW,上下文查询数据但保留了更改,而在第一个场景中,上下文查询了数据但忽略了任何添加的项目。它似乎有点不协调。
我是否正确理解这一点,或者我错过了什么?
感谢您的帮助。
答案 0 :(得分:3)
不,因为它在数据库中尚不存在。但是,它可以通过ObjectContext的ObjectStateManager访问,或者,如果您使用DbContext / DbSet包装器,则可以通过DbSet的.Local属性访问。
在编辑的情况下,您看到ORM的第一级缓存在工作。查询是针对数据库执行的(因此与那里的值进行比较 - 如果你在上下文中修改了Lastname,你的例子会变得更奇怪,但仍然会从查询中查找未修改的Lastname的结果),但是处理结果,首先检查返回实体的ID,并且由于具有该ID的实体已经存在于上下文中,因此您将获得该实例。这是默认的“AppendOnly”操作模式。
我不知道你想做什么,但是当我想根据需要使用加载和未读实体的值的规则验证我的更改时,我必须了解所有这些。我最终启动了一个事务,使用“None”选项保存更改,在数据库中再次执行验证查询(然后包含数据的“合并”视图),如果是,则回滚事务数据无效,或accepting the changes并以其他方式提交交易。