Ste*_*ven 5 .net c# linq entity-framework
我刚刚尝试使用Entity Framework,但我对DBSet Object的某些行为感到有些困惑.当我调用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);
}
Run Code Online (Sandbox Code Playgroud)
(如果上下文有帮助,我这样做是因为我想设置一个单元测试,我用我满足特定测试环境的项目填充我的(本地)上下文...我很快就不必申请了这些变化因为它们真的只适用于那个特定的测试,但是如果需要的话我可以......在这样做的时候,我很惊讶地发现存储库在查询结果中没有包含更改的项目 - 除非我这样做FindByID - 所以我也希望我能解决这个明显的不一致,或者更好地解释为什么那不可行......或者不是一个好主意?:))
例外情况是这样的:您不能将实体类型(通用类型 T 的)列表发送到服务器来执行,Except并且Union在 SQL 中使用这些“常量”对象的集合。基本上,您必须使用LINQ to Objects 在内存中应用Except和,这意味着:在服务器的过滤结果具体化之后(因此,在 之后的某个地方)。您必须再次将过滤器应用到上下文中处于状态的对象列表。Union.ToList()Added