Entity Framework Caching Issue

后端 未结 12 2186
無奈伤痛
無奈伤痛 2020-12-08 00:19

I am new to Entity Framework.

I have get to some values in my database using EF. It returns perfectly, and the values are shown in labels. But When I delete all valu

相关标签:
12条回答
  • 2020-12-08 00:33

    Firstly I would not suggest modifying the database external to your system unless you are only doing testing and development.

    The EF DbContext contains an IDisposable interface. To release any cached data either make the Dispose calls manually or place your Database Object inside a using block.

            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();
                }
            }
    

    This will make sure the context is cleared and recreated the next time it is used. Make sure to do this for all your calls and not just the one you are having issues with.

    0 讨论(0)
  • 2020-12-08 00:35

    When you use EF it by default loads each entity only once per context. The first query creates entity instace and stores it internally. Any subsequent query which requires entity with the same key returns this stored instance. If values in the data store changed you still receive the entity with values from the initial query

    A careful answer:

    https://stackoverflow.com/a/3653392/1863179

    0 讨论(0)
  • 2020-12-08 00:36

    I suspect that the underlying problem here is that your DbContext is hanging around too long. I can tell from the fact that you are using HttpContext that you have a web application, and General guidelines when working with DbContext include

    When working with Web applications, use a context instance per request.

    If you are using MVC you could use the Dispose pattern in your controller like this:

    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);
        }
    }
    

    But you really ought to be looking at dependency injection to manage the DbContext lifetime

    0 讨论(0)
  • 2020-12-08 00:39

    EF will not load changes unless you re query the context. EF queries db and loads maps them into objects, it watches changes you perform on objects and not on the database. EF does not track changes made directly to database and it will never track.

    You have loaded a List, that List is your cache in memory. Even calling Save Changes will not refresh. You will have to query the context once again, that is create new list.

    To see changes You will have to execute following line once more,

    datamodel.Compliances.Where(c => c.School.DistrictId == districtId).ToList()
    
    0 讨论(0)
  • 2020-12-08 00:39

    I think you should follow some of the other solutions here, but it seems like you're wanting to clear the cache. You can achieve this by doing the following:

    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
    
    0 讨论(0)
  • 2020-12-08 00:40

    I recommend you to use some MergeOption to all EntitieSet after create the context, like this:

    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;
    }
    

    Read about the MergeOption here: http://msdn.microsoft.com/en-us/library/system.data.objects.mergeoption.aspx Your will use NoTracking, I think.

    If you want to CLEAR the "cached" entities, detaching it.

    var entidades = Ctx.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified | EntityState.Unchanged);
    foreach (var objectStateEntry in entidades)
        Ctx.Detach(objectStateEntry.Entity);
    

    Where Ctx are my Context.

    0 讨论(0)
提交回复
热议问题