Nhibernate 保存更改前从ObjectContext获取新添加的实体

Nhibernate 保存更改前从ObjectContext获取新添加的实体,nhibernate,entity-framework,unit-of-work,identity-map,Nhibernate,Entity Framework,Unit Of Work,Identity Map,好的,我读了这些: 我想这个问题没有明确的解决方案(虽然第二篇文章是2009年的),但我认为这是实体框架的一个重要问题,所以不管怎样,我还是会问我的问题 假设我们有这样的代码: // Get somehow an UnitOfWork instance, e.g. using factory var categoryRepository = new CategoryRepository(unitOfWork); var newCategory = new Category("Some Ca

好的,我读了这些:

我想这个问题没有明确的解决方案(虽然第二篇文章是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()(因为我们不想在业务事务结束之前提交)?如果答案是“否”,那么这不是特别违反了身份地图设计模式和整体工作单元模式吗?如果您使用EF,如何处理这种情况

提前谢谢


抱歉耽搁了,伙计们

看来你不明白我的意思。问题不是“如何恢复我刚才添加的实例?”毕竟我有一个参考。问题是“任何新添加的(仍然未提交-实际上可能永远不会提交)实体如何被给定数据库集上的任何查询考虑?”

如果我添加了一个新的类别,然后写了类似的内容(我故意不在这里使用repository,而是使用row DbContext(如果我们使用EF 4.0,则使用ObjectContext)以便更清楚地了解您):

如果满足条件,我希望在结果集中返回我的新类别。这个查询可能会在另一个方法(甚至是另一个类)中执行,该方法在单个事务(工作单元)中共享相同的上下文(存储库)。 我知道我可以对Categories.Local执行相同的查询,只将结果过滤到新添加的实体(因为Local包含当前正在跟踪的集合的所有实体),并将其与数据库返回的结果相结合。你不觉得它很丑吗?我甚至不确定我现在是否错过了什么。所有这些都是ORM的工作。这都是关于事务行为(工作单元)的,ORM应该处理它(就像NHibernate一样)


现在你觉得有意义了吗?

你链接的第一个问题怎么没有回答你的问题?那里的代码运行良好,并满足您的要求。您的抱怨似乎是您的
类别repository.GetAll
没有使用它。好吧,那是你的密码。修复它。对于
DbContext
(EF 4.1)有
Local
DbContext.Categories.Local.Contains(newCategory)
将按照您的预期运行。EF 4.1中的
Local
实际上只是封装了与第一个链接问题类似的查询。您链接的第一个问题如何不能回答您的问题?那里的代码运行良好,并满足您的要求。您的抱怨似乎是您的
类别repository.GetAll
没有使用它。好吧,那是你的密码。修复它。对于
DbContext
(EF 4.1)有
Local
DbContext.Categories.Local.Contains(newCategory)
将按照您的预期运行。EF 4.1中的
Local
实际上只是封装了与第一个链接问题类似的查询。
var selectedCategories = context.Categories.Where(c => c.ParentCategory.Name == "Some Category Name");