0

i want to store often loaded data from my database to my servers MemoryCache in my web application. Every time a class will access the cache and get the object there is a ObjectDisposedException exception on the references from the object. So i need to know if i can store a object with all references somewhere outside the database.

For example: Here are the main methods of my ModelCache. The other methods are Singelton and the GlobalCachingProvider is implemented as usual:

public virtual bool GetAnimalLineFromCache(int id, int userId, out AnimalLine animalLine, out Dictionary<PermissionEnum, bool> permissions)
{
    try
    {
        Tuple<AnimalLine, Dictionary<IAzaraUser, Dictionary<PermissionEnum, bool>>> dic;
        if (GlobalCachingProvider.Instance.CheckIfSpecificCacheExists("AnimalLine_" + id))
        {
            dic = GlobalCachingProvider.Instance.GetItem("AnimalLine_" + id) as Tuple<AnimalLine, Dictionary<IAzaraUser, Dictionary<PermissionEnum, bool>>>;
            animalLine = dic.Item1 as AnimalLine;
            if (dic.Item2.Any(c => c.Key.Id == userId))
            {
                permissions = dic.Item2.SingleOrDefault(x => x.Key.Id == userId).Value;
                return true;
            }
            else
            {
                permissions = null;
                return false;
            }
        }
        else
        {
            animalLine = null;
            permissions = null;
            return false;
        }
    }
    catch (Exception exc)
    {
        using (var dataContext = new AzaraDataContext())
        {
            var errorManagement = new ErrorLogManagement(dataContext);
            errorManagement.InsertErrorLog(exc.Message, exc.StackTrace, "ModelCacheManagement", "GetAnimalLineFromCache");
        }
        animalLine = null;
        permissions = null;
        return false;
    }
}

public virtual void StoreAnimalLineInCache(AnimalLine animalLine, IAzaraUser user, bool read, bool edit, bool delete)
{
    try
    { 
        if (user == null) user = new AzaraUser() { Id = 0 };
        Tuple<AnimalLine, Dictionary<IAzaraUser, Dictionary<PermissionEnum, bool>>> dic;
        if (GlobalCachingProvider.Instance.CheckIfSpecificCacheExists("AnimalLine_" + animalLine.Id))
        {
            dic = GlobalCachingProvider.Instance.GetItem("AnimalLine_" + animalLine.Id) as Tuple<AnimalLine, Dictionary<IAzaraUser, Dictionary<PermissionEnum, bool>>>;
            var Permissions = new Dictionary<PermissionEnum, bool>();
            Permissions.Add(PermissionEnum.Read, read);
            Permissions.Add(PermissionEnum.Edit, edit);
            Permissions.Add(PermissionEnum.Delete, delete);
            dic.Item2.Add(user, Permissions);
            GlobalCachingProvider.Instance.ReplaceItem("AnimalLine_" + animalLine.Id, dic);
        }
        else
        {
            var Permissions = new Dictionary<PermissionEnum, bool>();
            Permissions.Add(PermissionEnum.Read, read);
            Permissions.Add(PermissionEnum.Edit, edit);
            Permissions.Add(PermissionEnum.Delete, delete);
            var dic2 = new Dictionary<IAzaraUser, Dictionary<PermissionEnum, bool>>();
            dic2.Add(user, Permissions);
            dic = Tuple.Create<AnimalLine, Dictionary<IAzaraUser, Dictionary<PermissionEnum, bool>>>(animalLine, dic2);
            GlobalCachingProvider.Instance.AddItem("AnimalLine_" + animalLine.Id, dic);
        }
    }
    catch (Exception exc)
    {
        using (var dataContext = new AzaraDataContext())
        {
            var errorManagement = new ErrorLogManagement(dataContext);
            errorManagement.InsertErrorLog(exc.Message, exc.StackTrace, "ModelCacheManagement", "StoreAnimalLineInCache");
        }
    }
}

Next here is one of the methods accessing those methods from controller or other class wit own DataContext instance:

  protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null) throw new ArgumentNullException("httpContext");
            int Id = 0;
            int userId = UserCacheManagement.Instance.GetUserFromCache(AzaraSession.Current.SessionID).GetUserId();
                       AnimalLine animalLine = null;
            Id = int.Parse((httpContext.Request.RequestContext.RouteData.Values["animalLineId"] as string) ?? (httpContext.Request["animalLineId"] as string)); break;
                           Dictionary<PermissionEnum, bool> permissions = null;
            ModelCacheManagement.Instance.GetAnimalLineFromCache(Id, userId, out  animalLine, out  permissions);
            if (permissions != null) return permissions[permissionType];
            using (var dataContext = new AzaraDataContext())
            {
                try
                {
                    PermissionControle permissionControle = new PermissionControle(dataContext);
                    IEntityManagement<AzaraUser> azaraUserManagement = new AzaraUserManagement(dataContext);
                    var user = userId != 0 ? azaraUserManagement.GetSingle(userId) : null;
                    var userVisibility = permissionControle.GetVisibility(String.IsNullOrEmpty(user.UserName) ? "" : user.UserName);
                    var lineManagement = new LineManagement(dataContext);
                        animalLine = lineManagement.GetSingle(Id) as AnimalLine;
                    ISecurableEntity iSecEnt = animalLine as ISecurableEntity;
                    var read = iSecEnt != null ? permissionControle.CanUserRead(user, iSecEnt) : false;
                    var edit = iSecEnt != null ? permissionControle.CanUserEdit(user, iSecEnt) : false;
                    var delete = iSecEnt != null ? permissionControle.CanUserDelete(user, iSecEnt) : false;
               ModelCacheManagement.Instance.StoreAnimalLineInCache(animalLine, user, read, edit, delete);
                    switch (permissionType)
                    {
                        case PermissionEnum.Read: return read;
                        case PermissionEnum.Edit: return edit;
                        case PermissionEnum.Delete: return delete;
                    }
                    return false;
                }
                catch (Exception exc)
                {
                    var errorManagement = new ErrorLogManagement(dataContext);
                    errorManagement.InsertErrorLog(exc.Message, exc.StackTrace, "PermissionAuthorizationAttribute", "AuthorizeCore");
                    return false;
                }
            }
        }
PX Roth
  • 139
  • 2
  • 16
  • Source code would be very helpful – Pseudonym Apr 08 '15 at 13:11
  • Yes, it's absolutely possible. I do it myself in a couple cases where I need fast access to database objects that don't need to be 100% fresh. You've definitely got a bug somewhere, so we need to see the code for the object you're caching it in. – Pharylon Apr 08 '15 at 13:16
  • I add the store/get method from the cache and one of the methods calling them. – PX Roth Apr 08 '15 at 13:17
  • Do you have navigation properties (with lazy loading)? – ssimeonov Apr 08 '15 at 13:21
  • I use default Linq to SQL and as i know i automatically use Lazy loading. That could be my problem, i will check this out. – PX Roth Apr 08 '15 at 13:23
  • I added load options for all entites i need and it still gives me the Exception. – PX Roth Apr 08 '15 at 13:56

0 Answers0