C# EF代码优先方法中的数据刷新问题

C# EF代码优先方法中的数据刷新问题,c#,wpf,entity-framework,C#,Wpf,Entity Framework,Hi Im使用实体框架代码优先方法和通用存储库模式开发WPF应用程序。我的问题是在运行WPF应用程序时,当我对数据库中的数据进行更改时,WPF应用程序数据没有显示修改后的最新数据。它将所有数据保留在缓存中,而不是与数据库同步。我必须关闭我的应用程序,并需要重新运行它以获得修改后的数据。我怎样才能解决这个问题。请帮忙 public class GenericRepository<TEntity> where TEntity : class { internal RcerpDbC

Hi Im使用实体框架代码优先方法和通用存储库模式开发WPF应用程序。我的问题是在运行WPF应用程序时,当我对数据库中的数据进行更改时,WPF应用程序数据没有显示修改后的最新数据。它将所有数据保留在缓存中,而不是与数据库同步。我必须关闭我的应用程序,并需要重新运行它以获得修改后的数据。我怎样才能解决这个问题。请帮忙

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()
尽管我强烈推荐

  • 使用新上下文并处理当前上下文
  • 对查询使用AsNoTracking()修饰符

  • 我认为关键是他不知道数据何时发生了变化。例如,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;
    }