C# 创建/编辑ASP.NET MVC EF 6.1后强制DBContext刷新
我有一个网站正在使用ASP.NET MVC 5和EF6.1,我有一个问题,它在编辑过程后显示旧数据。数据被正确地保存到数据库中,但是当重定向到索引视图时,它仍然显示旧数据 如果我回到编辑视图,它仍然显示旧数据。DBContext似乎没有刷新数据 我有一个基本控制器,它保存DBContext(如果这很重要的话) 以下是我的控制器中编辑视图的代码:C# 创建/编辑ASP.NET MVC EF 6.1后强制DBContext刷新,c#,asp.net-mvc,entity-framework,dbcontext,C#,Asp.net Mvc,Entity Framework,Dbcontext,我有一个网站正在使用ASP.NET MVC 5和EF6.1,我有一个问题,它在编辑过程后显示旧数据。数据被正确地保存到数据库中,但是当重定向到索引视图时,它仍然显示旧数据 如果我回到编辑视图,它仍然显示旧数据。DBContext似乎没有刷新数据 我有一个基本控制器,它保存DBContext(如果这很重要的话) 以下是我的控制器中编辑视图的代码: public ActionResult FeaturedItemEdit(int? id) { if (id == null)
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);
}
}
<strike>protected nfmContext db = new nfmContext();</strike>
没什么特别的。起初我认为这是因为调用都是async
,但将其改回非异步并没有多大区别。我还没有发布创建项目的代码,但是它有相同的问题
我甚至用[OutputCache(Location=System.Web.UI.OutputCacheLocation.None)]
装饰了我的控制器,以确保它不是客户端缓存问题
那么,我是做错了什么,还是有办法强迫DBContext从数据库中提取新记录
更新1:
以下是在基本控制器中初始化我的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);
}
}
<strike>protected nfmContext db = new nfmContext();</strike>
protected nfmContext db=new nfmContext();
这不再使用-请参阅更新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);
}
}
公共类nfmContext:DbContext
{
公共nfmContext():基本(“连接字符串”)
{
}
公共数据库集特性数据项{get;set;}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove();
modelBuilder.Conventions.Remove();
基于模型创建(modelBuilder);
}
}
更新2:我已将DBContect切换为每个方法的本地。上面的代码反映了这些更改,我已经从基本控制器中删除了DBContect属性。始终仅在需要时使用dbContext。通常在方法中使用using语句。
由于连接池的原因,重新打开与数据库的连接不会花费很长时间。始终仅在需要时使用dbContext。通常在方法中使用using语句。
由于连接池的原因,重新打开与数据库的连接不会花费很长时间。在深入研究并搜索项目中的各种缓存实现后,发现了问题 在某个时候,在项目中设置了(或引用的
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));
}
}
公共类配置:DbConfiguration
{
公共配置()
{
var transactionHandler=new CacheTransactionHandler(new InMemoryCache());
AddInterceptor(transactionHandler);
var cachingPolicy=新cachingPolicy();
装载+=
(发送方,args)=>args.ReplaceService(
(s,)=>新的CachingProviderServices(s,transactionHandler,
恶作剧政策);
}
}
一旦我从项目中删除了这段代码,系统就会像预期的那样完美地工作,但这也删除了额外缓存的功能
为了让它正常工作并让我能够按需清除DbSet
,我将CacheTransactionHandler
的声明切换为使用静态InMemoryCache
。然后,一旦设置为那样,我就可以使用InvalidateDbSets
从内存缓存中删除该项
下面是我具体做的:
- 将此添加到我的
:DbContext
public static readonly EFCache.InMemoryCache Cache=new EFCache.InMemoryCache()代码>
- 将配置子目录中的
transactionHandler
声明更改为:
var transactionHandler=新的CacheTransactionHandler(nfmContext.Cache)代码>
- 在任何
.SaveChanges
调用之后,我添加了:
nfmContext.Cache.InvalidateSets(新列表(){“[在此插入实体名称]”})代码>
现在一切都正常了,只要需要,它就会使用缓存。在任何时候进行更改后,我都会清除该缓存项,并在下一次中重新加载该缓存项。非常好。在深入研究项目并搜索各种缓存实现后发现了问题
在某个时候,在项目中设置了(或引用的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));
}
}
公共类配置:DbConfiguration
{
公共配置()
{
var transactionHandler=new CacheTransactionHandler(new InMemoryCache());
AddInterceptor(transactionHandler);
var cachingPolicy=新cachingPolicy();
装载+=
(发送方,args)=>args.ReplaceService(
(s,)=>新的CachingProviderServices(s,transactionHandler,
恶作剧政策);
}
}
一旦我从项目中删除了这段代码,系统就会像预期的那样完美地工作,但这也删除了额外缓存的功能
为了让它发挥作用并给予