2009-06-24 45 views
5

是否可以查询上下文,对实体进行更改,然后重新查询上下文并获取包含更改的实体的结果集,而不进行保存更改? (我不想保存更改,因为我可能想要回滚)查询实体框架包括尚未提交的记录

我知道我可以通过使用GetObjectStateEntries得到更改,但我对整个数据集感兴趣..不仅仅是更改的实体。

我认为做到这一点的唯一方法是使用savechanges,但是在所有事物中都包装一个事务处理器,以便我可以在没有满足条件时执行回滚。或者我错过了更容易的事情?

+0

你究竟想完成什么?为什么您在提交之前需要访问新的集合?你是否试图进行某种验证以防止重复或其他需要将插入/修改过的实体与集合中所有其他实体进行比较的其他内容? – Merritt 2009-06-25 15:05:23

+0

基本上是。这不是我想要阻止提交,而是想根据所有实体的当前状态(更改和未更改)的条件更新另一个实体。这是一个类似于工作流的业务规则。不幸的是,状态可以在不调用.savechanges()的不同服务中调用(使用缓存的上下文)。因此跟踪这些变化很难。 – itchi 2009-06-25 21:11:08

回答

3

为什么不将现有实体集合与要添加的实体合并?我测试了这一点,它似乎工作 - 它不占删除,虽然,但你应该能够得到的想法:

// get the entities that have been inserted or modified 
var projects = myObjectContext.ObjectStateManager.GetObjectStateEntries(
    EntityState.Added | EntityState.Modified).Where(
      x => x.Entity is Project).Select(x=> (Project) x.Entity); 

// get existing entities, exclude those that are being modified 
var projects2 = myObjectContext.Projects.Where(
    BuildDoesntContainExpression<Project, int>(z => z.ProjectId, 
      projects.Select(x => x.ProjectId))); 

// Union the 2 sets 
var projects3 = projects.Union(projects2); 

BuildDoesntContainExpression:不能使用含有,因此,你由于某些原因无法做到与EF相反,所以使用这种方法:

private static Expression<Func<TElement, bool>> BuildDoesntContainExpression<TElement, TValue>( 
     Expression<Func<TElement, TValue>> valueSelector, IEnumerable<TValue> values) 
    {  
     if (null == valueSelector) 
     { 
      throw new ArgumentNullException("valueSelector"); 
     } 

     if (null == values) 
     { 
      throw new ArgumentNullException("values"); 
     }  

     ParameterExpression p = valueSelector.Parameters.Single();  

     // p => valueSelector(p) == values[0] || valueSelector(p) == ... 
     if (!values.Any())  
     {   
      return e => false;  
     }  

     var equals = values.Select(
      value => (Expression)Expression.NotEqual(valueSelector.Body, Expression.Constant(value, typeof(TValue))));  

     var body = equals.Aggregate<Expression>((accumulate, equal) => Expression.And(accumulate, equal));  

     return Expression.Lambda<Func<TElement, bool>>(body, p); 
    }