C# 使实体框架缓存失效/禁用
我看到有很多关于EF缓存的问题,但我还没有找到解决问题的方法 直截了当的问题是 如何完全禁用实体框架6缓存?或者,我可以通过编程方式告诉EF忘记缓存,因为数据发生了一些问题吗 背景 首先,我继承了一个应用程序,它由EF(首先定义实体的模型)和普通的SQL(操作数据)混合而成。我所做的是重构应用程序,以便:C# 使实体框架缓存失效/禁用,c#,linq,entity-framework,caching,C#,Linq,Entity Framework,Caching,我看到有很多关于EF缓存的问题,但我还没有找到解决问题的方法 直截了当的问题是 如何完全禁用实体框架6缓存?或者,我可以通过编程方式告诉EF忘记缓存,因为数据发生了一些问题吗 背景 首先,我继承了一个应用程序,它由EF(首先定义实体的模型)和普通的SQL(操作数据)混合而成。我所做的是重构应用程序,以便: 使用EF6 LINQ进行简单的查询(如实体的GetAll()) 在SQL中保留复杂的数据操作,必要时使用DbContext.Database.Connection 添加Spring.Web支
- 使用EF6 LINQ进行简单的查询(如实体的
)GetAll()
- 在SQL中保留复杂的数据操作,必要时使用
DbContext.Database.Connection
- 添加
支持以启用DI和事务(尚未)Spring.Web
控制器
方法如下
[HttpPost]
public ActionResult Index(string[] codice, string[] flagpf, string[] flagpg, string[] flagammbce, string[] flagammdiv, string[] flagammest,
string[] flagintab, string[] flagfinanz, string[] flagita, string[] flagest, string pNew){
Sottogruppo2015Manager.ActivateFlagFor("pf", flagpf);
Sottogruppo2015Manager.ActivateFlagFor("pg", flagpg);
Sottogruppo2015Manager.ActivateFlagFor("ammbce", flagammbce);
Sottogruppo2015Manager.ActivateFlagFor("ammdiv", flagammdiv);
Sottogruppo2015Manager.ActivateFlagFor("ammest", flagammest);
Sottogruppo2015Manager.ActivateFlagFor("intab", flagintab);
Sottogruppo2015Manager.ActivateFlagFor("finanz", flagfinanz);
Sottogruppo2015Manager.ActivateFlagFor("ita", flagita);
Sottogruppo2015Manager.ActivateFlagFor("est", flagest);
return RedirectToAction("Index", new { pNew });
}
每个字符串[]
参数都是表中的一列。ActivateFlagFor
方法按顺序运行两个查询
UPDATE table SET --param1-- = 0;
UPDATE table SET --param1-- = 1 where id in (--param2--)
当缓存启动时
以下是行为:
- 我首先加载页面,并发出一个LINQ select:检查来匹配列中的1和0
- 我更改一张或多张支票并提交
- 控制器发出查询以更新数据库中的检查
- 在重定向(!表示新请求!)重新加载页面之前,我检查数据库并应用更改
- 页面重新加载,并在上面发出相同的LINQ select:将显示旧检查
DbContext
当然,有些人可能会问“如何使用DbContext?”“是否正确地处理了它?”
- 我还没有将Spring事务集成到我的Manager类中
- 对数据库执行操作的每个对象都是扩展的
BaseManager
是一个请求范围的Spring对象。我已经实现了,但我目前实现了一个变通方法,虽然不好,在请求结束时正确地处理了DbContextDbContext
- :禁用延迟加载不起作用
- :
似乎可以解决这个问题,但我需要将它应用于十几个实体,以便将来某一天恢复Detach
AsNoTracking()
(在调用ToList()
或执行任何其他可能执行查询的操作之前)
请注意,这样做既不会检查缓存中的现有数据,也不会将数据库调用的结果添加到缓存中。此外,Entity Framework不会自动检测对从数据库检索的实体所做的更改。如果确实要更改任何实体并将其保存回数据库,则需要在调用SaveChanges()
之前附加已更改的实体
您的方法当前为:
public IList<Models.Example> GetAll()
{
return DataContext.example.ToList();
}
public IList GetAll()
{
返回DataContext.example.ToList();
}
它将改为:
public IList<Models.Example> GetAll()
{
return DataContext.example.AsNoTracking().ToList();
}
public IList GetAll()
{
返回DataContext.example.AsNoTracking().ToList();
}
如果您对处理EF缓存的其他选项感兴趣,我已经写了一篇文章。我也遇到了这个问题,但我可以解决它 我正在使用存储库模式并使用.NETCore的默认DI。 我一直在使用AddSingleton(…),但与DbContext一起使用是错误的 因此,我改为AddScoped,就像我从文档中读到的那样:作用域生存期服务在每个请求中创建一次。 它解决了我的问题
由于NOTRACKING并不总是好的,由于使用它,我有一个长期的尝试和搜索组成,因为,例如,记录无法删除。请允许我添加任何类型的附件对我不起作用…你在这里@deadManN中提到了这一点。如果你打开一个新问题并在这里链接到它,我很乐意帮助调查。但是没有任何细节都很难知道如何解决你的问题。我在这个问题上改变了我的方式,并解决了它…只是路过,我想我应该说it@deadManN您使用了哪种策略来禁用缓存?这对我帮助很大!
public IList<Models.Example> GetAll()
{
return DataContext.example.ToList();
}
public IList<Models.Example> GetAll()
{
return DataContext.example.AsNoTracking().ToList();
}