是否有一种方法可以在DBSet的查询中包含本地缓存项

本文关键字:查询 DBSet 包含本 缓存 方法 一种 是否 | 更新日期: 2023-09-27 18:05:08

我刚刚开始接触实体框架,但是我对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—所以我也希望我可以解决明显的不一致,或者更好地理解为什么这是不可行的……还是不是个好主意?:))

是否有一种方法可以在DBSet的查询中包含本地缓存项

异常说明:您不能将实体类型列表(泛型类型T)发送到服务器,以便在SQL中使用这些"常量"对象集合执行ExceptUnion。基本上,您必须将ExceptUnion应用于内存中,并使用LINQ to Objects,这意味着:之后的来自服务器的过滤结果已经具体化(因此,在.ToList()之后的某个地方)。您必须第二次对上下文中处于Added状态的对象列表应用过滤器。