Cache缓存了一个实体类(User),User共有5行数据User实体类中包含字段: uid admin password当我从Cache的User中取出一条数据 赋给一个新的User为什么当我改变新的 User里的字段值的时候,Cache里的User指定那条数据也跟着变化? 这样的问题如何解决意思就是 我取出Cache里的第二条记录赋给一个新的User当我改变新的User里的admin字段值为“CSDN” 的时候 Cache里的第二条记录的admin的值也变成“CSDN”了 有没有办法改变新的User值的时候 Cache里的保持不变

解决方案 »

  1.   

    引用类型互相赋值,只是把地址赋值了一下,他们都指向同一个堆的同一个对象。你定义的新的User变量实际上后你缓存里的指向的都是同一个User
    你需要做clone才行,而且要深copy。
      

  2.   

    也就是说你要new一个新的User,然后把那边的属性的值重新赋值给这个新的User。
      

  3.   


    朋友我Copy了 照样影响到 Cache中的数据!!!
      

  4.   

    你把copy的代码贴出来,我说的是深copy,就是User的属性如果是对象,也要做copy。否则有可能还是一样的。
      

  5.   


    我主题说的问题就是 我 new 新的User 了, 一样会改变Cache里的数据
      

  6.   

    然后你把对admin赋值的语句也贴出来,string的赋值啊什么的有点不同于普通对象之间的赋值的
      

  7.   

    如果你new了新的User按理是不会改变的,否则就不是cache的问题了,而是整个。netframework存在问题。所以你还是把代码贴出来看看。
      

  8.   

     例子:
    eit_Popedom Item = GetPopedom(1);Itm.Name = "abc" //当执行到这里的时候 Cache里的数据也跟着改变/////////以下是代码/////////
         #region [获取单条权限] EITCN.MODEL.eit_Popedom GetPopedom(int Id)
            /// <summary>
            /// 获取单条权限 
            /// </summary>
            /// <param name="Id"></param>
            /// <returns></returns>
            public static EITCN.MODEL.eit_Popedom GetPopedom(int Id)
            {
                Dictionary<int, EITCN.MODEL.eit_Popedom> Items = GetPopedomItems();
                if (!Items.ContainsKey(Id))
                {
                    return null;
                }
                return Items[Id];
            }
            #endregion
            /// <summary>
            /// 获取权限列表集合
            /// </summary>
            /// <returns></returns>
            public static Dictionary<int, EITCN.MODEL.eit_Popedom> GetPopedomItems()
            {
                Dictionary<int, EITCN.MODEL.eit_Popedom> Items = null;
                if (!EITCN.CACHE.CacheManager.GetValue<Dictionary<int, EITCN.MODEL.eit_Popedom>>("PopedomItems", out Items))
                {
                    Items = new Dictionary<int, EITCN.MODEL.eit_Popedom>();
                    using (DataTable dt = EITCN.DATA.DatabaseProvider.GetInstance().GetGroupsPopedom())
                    {
                        foreach (DataRow dr in dt.Rows)
                        {
                            EITCN.MODEL.eit_Popedom Item = new EITCN.MODEL.eit_Popedom();
                            Item = new EITCN.MODEL.eit_Popedom();
                            Item.Id = (int)dr["Id"];
                            Item.Name = dr["Name"].ToString();
                            Item.Sign = dr["Sign"].ToString().ToLower();
                            foreach (string Str in dr["BindGroup"].ToString().Trim().Split(','))
                            {
                                if (!string.IsNullOrEmpty(Str))
                                {
                                    Item.BindGroupId.Add(Convert.ToInt32(Str));
                                }
                            }
                            Item.ParentId = (int)dr["ParentId"];
                            Item.OrderID = (int)dr["Order"];
                            Item.arrChildID = GetChildID(dt, Item.Id);
                            Item.Child = Item.arrChildID.Split(',').Length;
                            Item.Depth = Depth(dt, Item.ParentId);
                            Item.LastNode = LastNode(dt, Item.ParentId, Item.OrderID);
                            Item.Path = GetParentID(dt, Item.Id);
                            Items.Add((int)dr["Id"], Item);
                        }
                    }
                }
                return Items;
            }using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;namespace EITCN.MODEL
    {
        public class eit_Popedom
        {
            private int m_Id;
            private string m_Sign;
            private string m_Name;
            private int m_Depth;
            private int m_Child;
            private string m_arrChildID;
            private string m_Path;
            private int m_OrderID;
            private bool m_LastNode;
            private int m_ParentId;
            private List<int> m_BindGroupId = new List<int>();        public int Id
            {
                get
                {
                    return m_Id;
                }
                set
                {
                    m_Id = value;
                }
            }        /// <summary>
            /// 唯一标记
            /// </summary>
            public string Sign
            {
                get
                {
                    return m_Sign;
                }
                set
                {
                    m_Sign = value;
                }
            }        /// <summary>
            /// 名称
            /// </summary>
            public string Name
            {
                get
                {
                    return m_Name;
                }
                set
                {
                    m_Name = value;
                }
            }        /// <summary>
            /// 允许绑定当前权限的用户组
            /// </summary>
            public List<int> BindGroupId
            { 
                get
                {
                    return m_BindGroupId;
                }
                set
                {
                    m_BindGroupId = value;
                }
            }        /// <summary>
            /// 父Id
            /// </summary>
            public int ParentId
            {
                get
                {
                    return m_ParentId;
                }
                set
                {
                    m_ParentId = value;
                }
            }        /// <summary>
            /// 深度
            /// </summary>
            public int Depth
            {
                get { return m_Depth; }
                set { m_Depth = value; }
            }        /// <summary>
            /// 此节点下所包含的节点数
            /// </summary>
            public int Child
            {
                get { return m_Child; }
                set { m_Child = value; }
            }        /// <summary>
            /// 子节点ID集合
            /// </summary>
            public string arrChildID
            {
                get { return m_arrChildID; }
                set { m_arrChildID = value; }
            }        /// <summary>
            /// 此节点行走路线 例如[1,4,9]
            /// </summary>
            public string Path
            {
                get { return m_Path; }
                set { m_Path = value; }
            }
            /// <summary>
            /// 排序
            /// </summary>
            public int OrderID
            {
                get { return m_OrderID; }
                set { m_OrderID = value; }
            }        /// <summary>
            /// 是否为最后节点[0/1]
            /// </summary>
            public bool LastNode
            {
                get { return m_LastNode; }
                set { m_LastNode = value; }
            }
        }
    }
      

  9.   

    ///////Cache类///////using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web;
    using System.Web.Caching;namespace EITCN.CACHE
    {
        public class CacheManager
        {
            /// <summary>
            /// 缓存时间方式
            /// </summary>
            public enum DateTimeType
            {
                /// <summary>
                /// 小时
                /// </summary>
                Hour = 0,
                /// <summary>
                /// 天数
                /// </summary>
                Day = 1,
            }        /// <summary>
            /// 新增缓存
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="Value"></param>
            /// <param name="datetimetype"></param>
            /// <param name="datetime"></param>
            public static void Add<T>(string key, T Value, DateTimeType datetimetype, int datetime)
            {
                Add<T>(key, Value, datetimetype, datetime, null, CacheItemPriority.NotRemovable);
            }        /// <summary>
            ///  新增缓存
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="Value"></param>
            /// <param name="datetimetype"></param>
            /// <param name="datetime"></param>
            /// <param name="file"></param>
            public static void Add<T>(string key, T Value, DateTimeType datetimetype, int datetime, CacheDependency file)
            {
                Add<T>(key, Value, datetimetype, datetime, file, CacheItemPriority.NotRemovable);
            }        /// <summary>
            /// 新增缓存
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="Value"></param>
            /// <param name="datetimetype"></param>
            /// <param name="datetime"></param>
            /// <param name="file"></param>
            /// <param name="cacheItemPriority"></param>
            public static void Add<T>(string key, T Value, DateTimeType datetimetype, int datetime, CacheDependency file, CacheItemPriority cacheItemPriority)
            {
                HttpRuntime.Cache.Add(key, Value, file, DateTime.Now.AddHours(datetime), TimeSpan.Zero, cacheItemPriority, null);
            }
            /// <summary>
            /// 更新缓存
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="value"></param>
            /// <param name="datetimetype"></param>
            /// <param name="datetime"></param>
            public static void Set<T>(string key, T value, DateTimeType datetimetype, int datetime)
            { 
            
            }        /// <summary>
            /// 更新缓存
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="Value"></param>
            /// <param name="datetimetype"></param>
            /// <param name="datetime"></param>
            /// <param name="file"></param>
            /// <param name="cacheItemPriority"></param>
            public static void Set<T>(string key, T Value, DateTimeType datetimetype, int datetime, CacheDependency file, CacheItemPriority cacheItemPriority)
            {
                Remove(key);
                Add<T>(key, Value, datetimetype, datetime, file, cacheItemPriority);
            }        /// <summary>
            /// 获取缓存
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <returns></returns>
            public static T Get<T>(string key)
            {
                return (T)HttpRuntime.Cache.Get(key);
            }        public static bool Get<T>(string key, out T value)
            {
                object obj = HttpRuntime.Cache.Get(key);
                if (obj == null)
                {
                    value = default(T);
                    return false;
                }
                else
                {
                    value = (T)obj;
                    return true;
                }
            }        /// <summary>
            /// 获取缓存
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public static bool GetValue<T>(string key, out T value)
            {
                if (HttpRuntime.Cache[key] == null)
                {
                    value = default(T);
                    return false;
                }
                else
                {
                    value = Get<T>(key);
                    return true;
                }
            }
            /// <summary>
            /// 清空缓存
            /// </summary>
            public static void Clear()
            {
                List<string> list = new List<string>();
                foreach (System.Collections.DictionaryEntry entry in HttpRuntime.Cache)
                {
                    list.Add(entry.Key.ToString());
                }
                foreach (string str in list)
                {
                    try
                    {
                        HttpRuntime.Cache.Remove(str);
                        continue;
                    }
                    catch
                    {
                        continue;
                    }
                }
            }        /// <summary>
            /// 移除缓存
            /// </summary>
            /// <param name="key"></param>
            public static void Remove(string key)
            {
                try
                {
                    HttpRuntime.Cache.Remove(key);
                }
                catch { }
            }
        }
    }
      

  10.   

    eit_Popedom Item = GetPopedom(1); 
    Itm.Name = "abc" //当执行到这里的时候 Cache里的数据也跟着改变 /////////以下是代码///////// 
        #region [获取单条权限] EITCN.MODEL.eit_Popedom GetPopedom(int Id) 
            /// <summary> 
            /// 获取单条权限 
            /// </summary> 
            /// <param name="Id"> </param> 
            /// <returns> </returns> 
            public static EITCN.MODEL.eit_Popedom GetPopedom(int Id) 
            { 
                Dictionary <int, EITCN.MODEL.eit_Popedom> Items = GetPopedomItems(); 
                if (!Items.ContainsKey(Id)) 
                { 
                    return null; 
                } 
                return Items[Id];         } 
            #endregion 老大,你直接拿的对象,哪里去重新new这个对象赋值了?
      

  11.   

    你new的是dictionary类,又不是Popedom类
    而且我看GetPopedomItems你这个方法里没有放到cache里的语句啊
    如果是你贴出来的代码,每次都会从数据库去拿的,没进缓存啊
      

  12.   


    我这样也试了还是不行eit_Popedom Item = new eit_Popedom();
    Item = GetPopedom(1); 
    Itm.Name = "abc" //当执行到这里的时候 Cache里的数据也跟着改变 
      

  13.   

     Dictionary <int, EITCN.MODEL.eit_Popedom> Items = GetPopedomItems(); 
    你的Popedom要实现一个这样的方法
    public eit_Popedom Clone()
    {
     eit_Popedom clone = new eit_Popedom();
    //将当前对象的所有属性赋给这个新对象,如果是对象,则也要实现它的clone,调用他的clone方法,直到它的属性都是值类型或者string类型。
    return clone;
    }
      

  14.   

    eit_Popedom Item = new eit_Popedom(); 
    Item = GetPopedom(1); 
    Itm.Name = "abc" //当执行到这里的时候 Cache里的数据也跟着改变 看来你还没明白引用类型的含义,你这样赋值跟前面的赋值是一样的Item = GetPopedom(1); 这句话覆盖了你前面的new的对象了
    这个变量你可以想象为一个指针,它已经指向你的缓存里的对象,而不是你new的对象了。
      

  15.   

    那具体要如何更改呢? 请指教 if (!EITCN.CACHE.CacheManager.GetValue <Dictionary <int, EITCN.MODEL.eit_Popedom>>("PopedomItems", out Items))   这里已经从缓存中取了 
      

  16.   

    并且一般放入缓存的数据,都是只读的,或者是大家共享的,就说即使改了值,也是合理的改动,像你这样,就必须要做clone了。
      

  17.   

    你的eit_Popedom要实现一个这样的方法 
    public class eit_Popedom
    {
    ...
    public eit_Popedom Clone() 

    eit_Popedom clone = new eit_Popedom(); 
    //将当前对象的所有属性赋给这个新对象,如果是对象,则也要实现它的clone,调用他的clone方法,直到它的属性都是值类型或者string类型。 
    return clone; 
    }

    }然后
       /// <summary> 
            /// 获取单条权限 
            /// </summary> 
            /// <param name="Id"> </param> 
            /// <returns> </returns> 
            public static EITCN.MODEL.eit_Popedom GetPopedom(int Id) 
            { 
                Dictionary <int, EITCN.MODEL.eit_Popedom> Items = GetPopedomItems(); 
                if (!Items.ContainsKey(Id)) 
                { 
                    return null; 
                } 
                return Items[Id].Clone(); 
            } 
      

  18.   


    没有必要执行Remove,相同ID的缓存会被覆盖的.
      

  19.   


    没有必要执行Remove,相同ID的缓存会被覆盖的.