在创建/编辑ASP.NET MVC EF 6.1之后强制DBContext刷新

时间:2017-02-17 13:43:06

标签: c# asp.net-mvc entity-framework dbcontext

我有一个使用ASP.NET MVC 5和EF6.1的网站,我在编辑程序后显示旧数据时遇到问题。数据正确保存到数据库,但重定向到索引视图时,它仍然显示旧数据。

如果我返回编辑视图,它仍会显示旧数据。 DBContext似乎没有刷新数据。

如果重要的话,我有一个保存DBContext的基本控制器。

这是我的控制器中编辑视图的代码:

public ActionResult FeaturedItemEdit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        using (nfmContext localContext = new nfmContext())
        {
            List<FeaturedItem> fi = localContext.FeaturedItems.AsNoTracking().ToList();

            FeaturedItem featuredItem = fi.Find(x => x.ID.Equals(id));

            if (featuredItem == null)
            {
                return HttpNotFound();
            }
            return View(featuredItem);
        }
    }

 [HttpPost]
[ValidateAntiForgeryToken]
public ActionResult FeaturedItemEditPost(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        using (nfmContext db = new nfmContext())
        {
            var item = db.FeaturedItems.Find(id);
            if (TryUpdateModel(item, "", new string[] { "ID", "Title", "ImageAlt", "ImagePath", "Link", "Visible", "Content" }))
            {
                try
                {
                    item.TimeStamp = DateTime.Now;
                    db.Entry(item).State = EntityState.Modified;
                    db.SaveChanges();

                    return RedirectToAction("FeaturedItems");
                }
                catch (DataException ex)
                {
                    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
                }
            }
            return View(item);
        }
    }

编辑完成后,它会返回到精选项目视图,该视图只会加载项目列表:

 public ActionResult FeaturedItems()
    {
         using (nfmContext localContext = new nfmContext())
        {
            return View(localContext.FeaturedItems.OrderBy(x => x.Visible).ThenBy(x => x.Title).AsNoTracking().ToList());
        }
    }

没有什么花哨的。起初我以为是因为调用都是async,但是在将其更改为非异步时,它并没有太大的区别。我没有发布创建项目的代码,但它有同样的问题。

我甚至用[OutputCache(Location = System.Web.UI.OutputCacheLocation.None)]装饰了我的控制器,以确保它不是客户端缓存问题。

那么,我做错了什么或有办法强制DBContext从数据库中提取新记录吗?

更新1: 这是在基本控制器中初始化我的DBContext的行:

        <strike>protected nfmContext db = new nfmContext();</strike>

不再使用 - 请参阅更新2

这是我的上下文设置:

 public class nfmContext : DbContext
{
    public nfmContext() : base("connectionStringHere")
    {
    }

    public DbSet<FeaturedItem> FeaturedItems { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

        base.OnModelCreating(modelBuilder);

    }
}

更新2:我已将DBContect切换为现在对每种方法都是本地的。上面的代码反映了这些更改,并且我已从基本控制器中删除了DBContect属性。

2 个答案:

答案 0 :(得分:0)

只要需要,请始终使用dbContext。通常在方法中使用using语句。 由于连接池,重新打开与数据库的连接不会花费很长时间。

答案 1 :(得分:0)

在挖掘并搜索项目以寻找各种缓存实现后,找出问题所在。

在某些时候,EntityFramework.Cache已在项目中设置(或EFCache,因为它已被引用)。这导致缓存问题,即使它是根据他们的文档设置的。

SaveChanges应该在事务中完成(我假设是这种情况)并且EFCache应该监视事务并刷新缓存。在这两个地方有一个故障,缓存没有到期。

供参考,以下是我用于实现框架的辅助缓存的内容:

    public class Configuration : DbConfiguration
{
    public Configuration()
    {
        var transactionHandler = new CacheTransactionHandler(new InMemoryCache());
        AddInterceptor(transactionHandler);

        var cachingPolicy = new CachingPolicy();

        Loaded +=
            (sender, args) => args.ReplaceService<DbProviderServices>(
                (s, _) => new CachingProviderServices(s, transactionHandler,
                cachingPolicy));
    }


}

一旦我从项目中删除了此代码,系统就会按预期完美运行,但这也消除了额外缓存的功能。

为了让它工作并让我能够按需清除DbSet,我将CacheTransactionHandler的声明切换为使用静态InMemoryCache。然后,一旦设置完成,我就可以使用InvalidateDbSets从内存缓存中删除该项。

这是我具体做的事情:

  • 将此添加到我的DbContext

public static readonly EFCache.InMemoryCache Cache = new EFCache.InMemoryCache();

  • 将Configuration子句中的transactionHandler声明更改为:

var transactionHandler = new CacheTransactionHandler(nfmContext.Cache);

  • 在任何.SaveChanges来电之后,我添加了:

nfmContext.Cache.InvalidateSets(new List<string>() { "[insert entity name here]" });

现在一切正常,它会在需要时使用缓存。在我做出更改之后,我会清除该缓存项并在下次重新加载。工作得很好。