我有一个使用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属性。
答案 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();
transactionHandler
声明更改为: var transactionHandler = new CacheTransactionHandler(nfmContext.Cache);
.SaveChanges
来电之后,我添加了: nfmContext.Cache.InvalidateSets(new List<string>() { "[insert entity name here]" });
现在一切正常,它会在需要时使用缓存。在我做出更改之后,我会清除该缓存项并在下次重新加载。工作得很好。