有没有办法在DBSet的查询中包含本地缓存的项目?

时间:2011-08-11 14:15:11

标签: c# .net linq entity-framework

我刚刚尝试使用Entity Framework,但我对DBSet对象的某些行为感到有些困惑。当我调用Find()方法时,它似乎知道我最近添加的(但尚未保存)项目的集合,但是当我尝试查询DBSet时,它似乎只包含一直存在的项目。有一种简单的方法可以解决这个问题吗?我包含了一些代码,我已经尝试解决这个问题,但当它开始迭代我的“已添加”更改集中的项目时,我收到此错误:

  

“无法创建EntityType类型的常量值。仅原始值   这里支持类型(例如Int32,String和Guid')   上下文中,“

internal DbContext Context  { get; set; }
protected DbSet<T> DBSet    { get; set; }

public virtual IEnumerable<T> Get(
    Expression<Func<T, bool>> filter = null,
    Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
    bool ignoreCachedChanges = false)
{
    IQueryable<T> oReturn = DBSet;

    // This block is intended to adjust the queryable source to account for changes
    if (!ignoreCachedChanges)
    {
        oReturn = oReturn.Except(Context.ChangeTracker.Entries<T>().Where(x => x.State == System.Data.EntityState.Deleted).Select(x => x.Entity));
        oReturn = oReturn.Union(Context.ChangeTracker.Entries<T>().Where(x => x.State == System.Data.EntityState.Added).Select(x => x.Entity));
    }
    if (filter != null)
        oReturn = oReturn.Where(filter);

    if (orderBy != null)
        return orderBy(oReturn).ToList();
    else
        return oReturn.ToList();
}

// NOTE: Get By ID uses Find which considers the queued-but-not-yet-applied changes
public virtual T GetByID(object id)
{
    return DBSet.Find(id);
}

(如果上下文有帮助,我这样做是因为我想设置一个单元测试,我用我的特定测试环境填充我的(本地)上下文...我很快就不会必须应用这些更改,因为它们实际上只适用于该特定测试,但我可以,如果需要...在执行此操作时,我惊讶地发现存储库未在其查询结果中包含已更改的项目 - 除非我正在做FindByID - 所以我也希望我能解决这个明显的不一致,或者更好地解释为什么那不可行......或者不是一个好主意?:))

1 个答案:

答案 0 :(得分:2)

异常说明:您不能向服务器发送实体类型列表(通用类型T),以便在SQL中使用这些“常量”对象集合执行ExceptUnion。基本上,您必须在LINQ to Objects的内存中应用ExceptUnion,这意味着:之后,来自服务器的过滤结果已经实现(因此,在{{1之后的某处) }})。您必须再次将过滤器应用于上下文中处于.ToList()状态的对象列表。