查询实体框架包括尚未提交的记录
问题描述:
是否可以查询上下文,对实体进行更改,然后重新查询上下文并获取包含更改的实体的结果集,而不进行保存更改? (我不想保存更改,因为我可能想要回滚)查询实体框架包括尚未提交的记录
我知道我可以通过使用GetObjectStateEntries得到更改,但我对整个数据集感兴趣..不仅仅是更改的实体。
我认为做到这一点的唯一方法是使用savechanges,但是在所有事物中都包装一个事务处理器,以便我可以在没有满足条件时执行回滚。或者我错过了更容易的事情?
答
为什么不将现有实体集合与要添加的实体合并?我测试了这一点,它似乎工作 - 它不占删除,虽然,但你应该能够得到的想法:
// 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);
}
你究竟想完成什么?为什么您在提交之前需要访问新的集合?你是否试图进行某种验证以防止重复或其他需要将插入/修改过的实体与集合中所有其他实体进行比较的其他内容? – Merritt 2009-06-25 15:05:23
基本上是。这不是我想要阻止提交,而是想根据所有实体的当前状态(更改和未更改)的条件更新另一个实体。这是一个类似于工作流的业务规则。不幸的是,状态可以在不调用.savechanges()的不同服务中调用(使用缓存的上下文)。因此跟踪这些变化很难。 – itchi 2009-06-25 21:11:08