好的,我读过这些:
EntityFramework show entities before saving changes
Where added objects are stored in ObjectContext?
我猜这个问题没有明确的解决方案(尽管第二篇文章是2009年),但我认为这是实体框架的一个重要问题,所以尽管如此我仍然会问我的问题。
假设我们有这样的代码:
// Get somehow an UnitOfWork instance, e.g. using factory
var categoryRepository = new CategoryRepository(unitOfWork);
var newCategory = new Category("Some Category");
categoryRepository.Add(newCategory);
var allCategories = categoryRepository.GetAll();
Debug.Assert(allCategories.Contains(newCategory));
unitOfWork.Commit();
如果我们使用NHibernate,UnitOfWork实现将封装一个ISession实例。并且给定的代码将按照我们的预期运行 - 我们可以在提交更改之前从存储库(即基础ISession)返回新添加的类别。
我很惊讶地发现实体框架表现不同。如果我们的UnitOfWork实现封装了EF的ObjectContext,则断言失败。在调用ObjectContext.SaveChages()之前(在unitOfWork.Commit()方法中),无法访问新添加的类别(通过相同的ObjectContext)。我试图找到一些ObjectContext属性来配置这种行为,但没有成功。
所以我的问题是:是否有可能从我们刚刚添加的ObjectContext中获取实体而无需调用ObjectContext.SaveChages()(因为我们不想在业务事务结束之前提交)?如果答案是“否”,那么这不是特别违反身份地图设计模式和一般的UnitOfWork模式吗?如果你使用EF如何处理这种情况?
提前致谢。
对不起,伙计们。
似乎你没有理解我的观点。问题不是“如何恢复我刚刚添加的这个实例?”毕竟我有一个参考。问题是“如何通过给定的DbSet上的任何查询来考虑任何新添加的(仍然未提交 - 实际上可能永远不会被提交)实体?”
如果我添加一个新类别,然后编写类似的东西(我故意不在这里使用存储库,但行DbContext(或者如果我们使用EF 4.0,则为ObjectContext)更清楚):
var selectedCategories = context.Categories.Where(c => c.ParentCategory.Name == "Some Category Name");
如果满足条件,我希望在结果集中返回我的新类别。可能此查询将在另一个方法(或甚至另一个类)中执行,该方法仅在单个事务(工作单元)内共享相同的上下文(存储库)。 我知道我可以通过Categories.Local执行相同的查询,仅将结果过滤到新添加的实体(因为Local包含当前正在跟踪的集合的所有实体),并将其与数据库返回的结果相结合。难道你不觉得它非常丑陋吗?而且我甚至不确定我现在是不是错过了什么。这一切都是ORM的工作。这完全取决于事务行为(工作单元),ORM应该处理它(就像NHibernate一样)。
现在对你有意义吗?