C# EF代码优先方法中的数据刷新问题
Hi Im使用实体框架代码优先方法和通用存储库模式开发WPF应用程序。我的问题是在运行WPF应用程序时,当我对数据库中的数据进行更改时,WPF应用程序数据没有显示修改后的最新数据。它将所有数据保留在缓存中,而不是与数据库同步。我必须关闭我的应用程序,并需要重新运行它以获得修改后的数据。我怎样才能解决这个问题。请帮忙C# EF代码优先方法中的数据刷新问题,c#,wpf,entity-framework,C#,Wpf,Entity Framework,Hi Im使用实体框架代码优先方法和通用存储库模式开发WPF应用程序。我的问题是在运行WPF应用程序时,当我对数据库中的数据进行更改时,WPF应用程序数据没有显示修改后的最新数据。它将所有数据保留在缓存中,而不是与数据库同步。我必须关闭我的应用程序,并需要重新运行它以获得修改后的数据。我怎样才能解决这个问题。请帮忙 public class GenericRepository<TEntity> where TEntity : class { internal RcerpDbC
public class GenericRepository<TEntity> where TEntity : class
{
internal RcerpDbContext Context;
internal DbSet<TEntity> DbSet;
public GenericRepository(RcerpDbContext context)
{
this.Context = context;
this.DbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = Null,
string includeProperties = "")
{
IQueryable<TEntity> query = DbSet;
if (filter != null)
{
query = query.Where(filter);
}
query = includeProperties.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries).Aggregate(query, (current, includeProperty) => current.Include(includeProperty));
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity GetById(object id)
{
return DbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
DbSet.Add(entity);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = DbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Delete(TEntity entityToDelete)
{
if (Context.Entry(entityToDelete).State == EntityState.Detached)
{
DbSet.Attach(entityToDelete);
}
DbSet.Remove(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
var entry = Context.Entry(entityToUpdate);
var primaryKey = DbSet.Create().GetType().GetProperty("Id").GetValue(entityToUpdate);
if (entry.State != EntityState.Detached) return;
var set = Context.Set<TEntity>();
var attachedEntity = set.Find(primaryKey);
if (attachedEntity != null)
{
var attachedEntry = Context.Entry(attachedEntity);
attachedEntry.CurrentValues.SetValues(entityToUpdate);
}
else
{
entry.State = EntityState.Modified;
}
}
}
公共类通用存储,其中tenty:class
{
内部RCERPDB上下文;
内部数据库集;
公共GenericRepository(RcerpDbContext上下文)
{
this.Context=Context;
this.DbSet=context.Set();
}
公共虚拟IEnumerable Get(
表达式筛选器=空,
Func orderBy=Null,
字符串includeProperties=“”)
{
IQueryable query=DbSet;
if(过滤器!=null)
{
query=query.Where(过滤器);
}
query=includeProperty.Split(新字符[]{',},StringSplitOptions.RemoveEmptyEntries)。聚合(query,(current,includeProperty)=>current.Include(includeProperty));
if(orderBy!=null)
{
returnorderby(query.ToList();
}
其他的
{
返回query.ToList();
}
}
公共虚拟实体GetById(对象id)
{
返回DbSet.Find(id);
}
公共虚拟空白插入(TEntity实体)
{
添加(实体);
}
公共虚拟无效删除(对象id)
{
TEntity entityToDelete=DbSet.Find(id);
删除(entityToDelete);
}
公共虚拟无效删除(TEntity entityToDelete)
{
if(Context.Entry(entityToDelete.State==EntityState.Detached)
{
数据库集连接(entityToDelete);
}
DbSet.Remove(entityToDelete);
}
公共虚拟无效更新(TEntity entityToUpdate)
{
var entry=Context.entry(entityToUpdate);
var primaryKey=DbSet.Create().GetType().GetProperty(“Id”).GetValue(entityToUpdate);
if(entry.State!=EntityState.Detached)返回;
var set=Context.set();
var attachedEntity=set.Find(primaryKey);
如果(附件身份!=null)
{
var attachedEntry=Context.Entry(attachedEntity);
附件.CurrentValues.SetValues(entityToUpdate);
}
其他的
{
entry.State=EntityState.Modified;
}
}
}
一旦知道新的DbContext已刷新(或者如果要检查是否有任何数据已更改),则需要创建一个新的DbContext
您的存储库应该要求注入Func
,以便在知道需要从数据库重新加载数据集合后,可以处置当前上下文,并使用Func
创建一个新上下文
否则,如果只想重新加载单个实体,则可以使用:
Context.Entry<T>(entity).Reload()
尽管我强烈推荐
我认为关键是他不知道数据何时发生了变化。例如,WPF应用程序正在运行,数据直接在数据库中更改。应用程序没有为此获取触发器。是。问题是我无法跟踪数据何时更改。有没有办法绕过缓存数据并直接从数据库中获取数据。@PhilipStuyck考虑到“有没有办法绕过缓存数据并从数据库中获取数据”这句话听起来他的问题是EF正在将实体的
本地
副本还给他,因此,他无法检查是否有任何变化。简单的再查询就足够了,每次再查询时,您都会再次前往db。如果要访问本地数据,必须使用DbSet.local。关键是你根本不需要一个新的环境。我仍然认为关键是op不知道db什么时候改变了,所以即使是刷新按钮也不够,用户应该什么时候按下按钮?因此,我在开始时向op提出了问题。不是每个请求都会转到Db,如果您在主键上使用筛选器进行查找/查询,EF将首先转到Local set,查看它是否已经有。您对刷新按钮感到满意,还是需要自动重新加载?
Context.Set<TEntity>.AsNoTracking()
Context.Set<Car>().Local.ToList().ForEach( x=>
{
Context.Entry(x).State = EntityState.Detached;
}