简体   繁体   English

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

[英]Data refreshing issue in EF code first method

Hi Im developing an WPF application using Entity Framework Code first method and Generic Repository pattern. 您好,我使用实体框架代码优先方法和通用存储库模式开发WPF应用程序。 My problem is at the time WPF application is running when I do a change to the data in the data base, WPF application data not showing that modified latest data. 我的问题是,当我对数据库中的数据进行更改时,WPF应用程序正在运行时,WPF应用程序数据未显示修改后的最新数据。 it is keeping all the data in the cache and not getting synch with the database. 它会将所有数据保留在缓存中,并且不会与数据库同步。 I have to close my application and need to rerun it to get the modified data. 我必须关闭我的应用程序,并且需要重新运行它才能获取修改后的数据。 How can i resolve this problem. 我该如何解决这个问题。 please help 请帮忙

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;
        }
    }

}

You need to create a new DbContext once you know it is refreshed (or if you want to check if any data has changed). 一旦知道新的DbContext已刷新(或者是否要检查是否有任何数据更改),就需要创建一个新的DbContext。

Your repository should ask for a Func<RcerpDbContext> to be injected, so it can dispose of the current context, and create a new one using the Func<> , once it knows it needs reload collections of data from the database. 您的存储库应要求注入Func<RcerpDbContext> ,以便可以处置当前上下文,并在知道需要从数据库重新加载数据集合后使用Func<>创建一个新上下文。

Otherwise if you only want to reload a single entity, you can use: 否则,如果您只想重新加载单个实体,则可以使用:

Context.Entry<T>(entity).Reload()

Also if you do not want EF to keep a local copy you can use 另外,如果您不希望EF保留本地副本,则可以使用

Context.Set<TEntity>.AsNoTracking()

which will force EF not to store any local copies. 这将迫使EF不要存储任何本地副本。 Beware, that if you change your entity, and try to call SaveChange() NOTHING will happen. 当心,如果你改变你的实体,并尝试调用SaveChange() 什么也不会发生。 You will manually have to tell EF which propertied have been updated. 您将必须手动告诉EF哪个资产已更新。

EDIT 1 编辑1

If you want to reload a whole set: 如果要重新加载整个集:

Context.Set<Car>().Local.ToList().ForEach( x=>
{
  Context.Entry(x).State = EntityState.Detached;
}

Although I would highly recommend either 尽管我强烈建议两者之一

  1. Using a new Context and disposing of current one. 使用新的上下文并处理当前上下文。
  2. Using the AsNoTracking() modifier for your queries. 对查询使用AsNoTracking()修饰符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM