entity frameworkcaching问题
我是entity framework的新手。
我已经在我的数据库中使用EF得到了一些值。 它完美地返回,值显示在标签中。 但是,当我删除我的表中的所有值(不使用EF),EF查询返回我的旧值。 我知道EF将这些值存储在caching中,并返回caching的数据以供后续运行。 它是否正确?
那么我怎样才能解决问题,当我已经删除了我的数据库中的所有值,但EF返回旧值?
编辑 :
现在我使用datamodel.SaveChanges()
。 但现在它返回相同的旧值。
我的示例查询如下所示:
SchoolBriefcaseEntities datamodel = new SchoolBriefcaseEntities(); datamodel.SaveChanges(); List<Compliance> compliance=new List<Compliance>(); IList<ComplianceModel> complianceModel; if (HttpContext.Current.User.IsInRole("SuperAdmin")) { compliance = datamodel.Compliances.Where(c => c.School.DistrictId == districtId).ToList(); }
如果您知道EF以外发生了更改,并且想要刷新特定实体的ctxt,则可以调用ObjectContext.Refresh
datamodel.Refresh(RefreshMode.StoreWins, orders);
如果这看起来像是常见的事情,那么应该在查询中禁用对象caching:
SchoolBriefcaseEntities datamodel = new SchoolBriefcaseEntities(); datamodel.tblCities.MergeOption = MergeOption.NoTracking;
或者为了closures特定实体的对象级caching,
Context.Set<Compliances>().AsNoTracking();
在使用EF时,默认情况下,每个上下文只加载一次实体。 第一个查询创build实体实例并将其存储在内部。 后续任何需要具有相同键的实体的查询都将返回此存储的实例。 如果数据存储中的值发生更改,您仍然收到来自初始查询的值的实体
仔细的回答:
除非重新查询上下文,否则EF不会加载更改。 EF查询数据库和加载将其映射到对象中,它监视您在对象上执行的更改,而不是数据库上执行的更改。 EF不会跟踪直接对数据库所做的更改,也不会跟踪。
你已经加载了一个List,List是你在内存中的caching。 即使调用保存更改也不会刷新。 你将不得不再次查询上下文,这是创build新的列表。
要查看更改您将不得不再次执行以下行,
datamodel.Compliances.Where(c => c.School.DistrictId == districtId).ToList()
我想你应该在这里遵循一些其他的解决scheme,但似乎你想清除caching。 您可以通过执行以下操作来实现此目的:
var count = datamodel.Compliances.Local.Count; // number of items in cache (ex. 30) datamodel.Compliances.Local.ToList().ForEach(c => { datamodel.Entry(c).State = EntityState.Detached; }); count = datamodel.Compliances.Local.Count; // 0
下面的代码帮助我的对象刷新新的数据库值。 Entry(object).Reload()命令强制对象调用数据库值
GM_MEMBERS member = DatabaseObjectContext.GM_MEMBERS.FirstOrDefault(p => p.Username == username && p.ApplicationName == this.ApplicationName); DatabaseObjectContext.Entry(member).Reload();
我build议你在创build上下文之后使用一些MergeOption到所有EntitieSet,如下所示:
var objSetProps = ctx.GetType().GetProperties().Where(prop => prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(ObjectSet<>)); foreach (PropertyInfo objSetProp in objSetProps) { ObjectQuery objSet = (ObjectQuery)objSetProp.GetValue(ctx, BindingFlags.GetProperty, null, null, null); objSet.MergeOption = MergeOption.PreserveChanges; }
阅读有关MergeOption在这里: http : //msdn.microsoft.com/en-us/library/system.data.objects.mergeoption.aspx你会使用NoTracking,我认为。
但是,你要清除“caching”的实体,把它分开。
var entidades = Ctx.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged); foreach (var objectStateEntry in entidades) Ctx.Detach(objectStateEntry.Entity);
Ctx是我的上下文。
首先,我不会build议修改系统外部的数据库,除非你只是在进行testing和开发。
EF DbContext包含一个IDisposable接口。 要释放任何caching的数据,请手动进行Dispose调用,或者将数据库对象放在使用块中。
using (SchoolBriefcaseEntities datamodel = new SchoolBriefcaseEntities()) { List<Compliance> compliance = new List<Compliance>(); IList<ComplianceModel> complianceModel; if (HttpContext.Current.User.IsInRole("SuperAdmin")) { compliance = datamodel.Compliances.Where(c => c.School.DistrictId == districtId).ToList(); } }
这将确保上下文在下次使用时被清除并重新创build。 请务必为您的所有来电执行此操作,而不仅仅是您遇到的问题。
我怀疑这里的根本问题是你的DbContext
挂了太久。 我可以从事实certificate你正在使用HttpContext
,你有一个Web应用程序,并且使用DbContext的一般准则包括
在使用Web应用程序时,请使用每个请求的上下文实例。
如果你使用的是MVC,你可以像这样在控制器中使用Dispose模式:
public class EmployeeController : Controller { private EmployeeContext _context; public EmployeeController() { _context = new EmployeeContext(); } public ActionResult Index() { return View(_context.Employees.ToList()); } protected override void Dispose(bool disposing) { if (disposing) { _context.Dispose(); } base.Dispose(disposing); } }
但是你真的应该看着dependency injection来pipe理DbContext生命周期
我认为你需要的是GetDatabaseValues()
。 它用于:
context.Entry(/*your entry*/).GetDatabaseValues();
以下信息来自msdn :
当前值是实体当前包含的值。 原始值是查询实体时从数据库中读取的值。 数据库值是当前存储在数据库中的值。 自从查询实体以来,如果数据库中的值可能发生更改(例如,另一个用户对数据库进行并发编辑时),那么获取数据库值非常有用。
夫妇可以做的事情。
- 使用新的上下文。 caching的实体存储在上下文中。 使用新的上下文阻止它使用caching。
- 如果你真的想要一个全局/持久的上下文,你有两个子选项:a。)总是调用Reload方法。 db.Entry(entity).Reload()…这迫使上下文重新加载该实体。 b。)使用SqlDependency对象来检测logging何时更改和重新加载实体。 https://code.msdn.microsoft.com/How-to-use-SqlDependency-5c0da0b3
- Web API和ValidateAntiForgeryToken
- jQuery中$ .getJSON()和$ .ajax()之间的区别
- Visual Studio – Resx文件默认“内部”为“公共”
- ASP.NET Web API:正确的方式返回401 /未授权的响应
- 我如何创build一个System.Guidtypes的路由约束?
- 通过POST(ajax)发送JSON数据并从Controller(MVC)接收json响应
- 在asp.net-mvc中如何连接Application_BeginRequest()
- 是否有一个最佳做法,并推荐替代MVC中的会话variables
- 如何用剃刀视图引擎简洁地创build可选的HTML属性?