2014-09-04 5 views
0

클래스 라이브러리에 캐싱을 구현했는데 문제가 있습니다. 내가하는 일은 XML 파일에서 읽어야하는 값을 전달하고 노드와 값을 반환합니다. 나는 childnodes를 키 값 쌍으로 저장하기 위해 사전을 사용했다. 내가 위의 기능을 "CompanyDetails, 이메일"와 같은 문자열을 전달합니다,캐시 값을 덮어 쓰시겠습니까?

<?xml version="1.0" encoding="utf-8"?> 
<Settings> 
    <Test1> 
     <CompanyDetails> 
     <Name>Test1</Name> 
     <Address1>Add1</Address1> 
     <Address2>Add2</Address2> 
     <Address3>Add3</Address3> 
     <Phone>1111</Phone> 
     </CompanyDetails> 
     <Email> 
     <Contact>[email protected]</Contact> 
     </Email> 
     <AdminUsers> 
     <User1>user1</User1> 
     <User2>user2</User2> 
     </AdminUsers> 
    </Test1> 
    </Settings> 

위 내 XML 예제에서

using System.Web; 
public Dictionary<string, string> GetDataFromSettings(string strValues) 
{ 
Dictionary<string, string> dictValus = new Dictionary<string, string>(); 
    XmlDocument xmlDoc = new XmlDocument(); 
    string xmlFilePath = "D:\\Test.xml"; 
    xmlDoc.Load(xmlFilePath); 
    if (!(xmlDoc == null)) 
    { 
     string[] splitValues = strValues.Split(new char[] { ',' }); 
     if (splitValues.Length > 1) 
     { 
      Dictionary<string, string> strDictValues = new Dictionary<string, string>(); 
      foreach (string strName in splitValues) 
      { 
       if (HttpRuntime.Cache[strName.Trim()] == null) 
       { 
        strDictValues.Clear(); 
        XmlNodeList xmlList = xmlDoc.SelectNodes("Settings/Test1/" + strName.Trim()); 

        foreach (XmlNode node in xmlList) 
        { 
         if (node.FirstChild.Name.ToString() != node.LastChild.Name.ToString()) 
         { 
          foreach (XmlNode childNode in node.ChildNodes) 
          { 
           strDictValues.Add(strName.Trim() + "." + childNode.LocalName, childNode.InnerText); 
          } 
         } 
         else 
         { 
          strDictValues.Add(strName.Trim() + "." + node.FirstChild.LocalName, node.InnerText); 
         } 
        } 
        HttpRuntime.Cache.Insert(strName.Trim(), strDictValues,new System.Web.Caching.CacheDependency(xmlFilePath)); 
       } 
       else 
       { 
        Dictionary<string, string> tmpDict = new Dictionary<string, string>(); 
        tmpDict = (Dictionary<string, string>)HttpRuntime.Cache[strName.Trim()]; 

        foreach (var tmpVal in tmpDict) 
        { 
         strDictValues.Add(tmpVal.Key, tmpVal.Value); 
        } 
       } 

       foreach (var tmpStrDict in strDictValues) 
       { 
        dictValus.Add(tmpStrDict.Key, tmpStrDict.Value); 
       } 
      } 
     } 
    } 
    return dictValus; 
    } 

아래에 내 코드를 참조하십시오 내 XML의 예를보고 난 분할하십시오 그런 다음 각 문자열을 캐시에 별도로 저장하십시오. 처음으로 실행할 때 "CompanyDetails"아래의 값은 "CompanyDetails"라는 캐시에 저장되고 노드 "Email"에 대해 캐시하면 [ "CompanyDetails"] 캐시가 덮어 쓰여지고 캐시됩니다 [ "Email "]이 만들어지고 둘 다 같은 값을 갖습니다. 이것은 정확하지 않습니다. 나는 그것이 일어나고있는 이유를 찾을 수 없다.

감사합니다,
Jollyguy

+0

는 왜해야합니까'splitValues.Length> 'splitValues.Length> 0' 대신에 '1'을 사용합니까? '> 1'을 검사하면 하나의 키에 대한 값을 캐시하지 않는다는 것을 의미합니다. 설명을 주신 덕분에 – dbc

답변

0

문제는, 당신이 캐시를 구축 할 때 명확하고 각 strName 키에 대한 새 사전을 만들보다는 사전을 다시 사용합니다. 삭제 한 사전은 캐시에 추가 된 사전이므로 이 아니며 사전을 복사하지만 참조 만 저장하면 이전 값이 지워집니다.

다음과 같이 해보십시오 (I 디버깅의 편의를 위해 약간 낮은 수준의 버전을 리팩토링, 중복 호출을 제거주의에 "strName.Trim()") :

public Dictionary<string, string> GetDataFromSettings(TextReader reader, string xmlFilePath, string strValues) 
    { 
     XmlDocument xmlDoc = new XmlDocument(); 
     xmlDoc.Load(reader); 
     return GetDataFromSettings(xmlDoc, xmlFilePath, strValues); 
    } 

    public Dictionary<string, string> GetDataFromSettings(XmlDocument xmlDoc, string xmlFilePath, string strValues) 
    { 
     Dictionary<string, string> dictValus = new Dictionary<string, string>(); 
     if (!(xmlDoc == null)) 
     { 
      string[] splitValues = strValues.Split(new char[] { ',' }); 
      if (splitValues.Length > 1) 
      { 
       foreach (string strName in splitValues.Select((s) => s.Trim())) 
       { 
        Dictionary<string, string> strDictValues = new Dictionary<string, string>(); 
        if (HttpRuntime.Cache[strName] == null) 
        { 
         XmlNodeList xmlList = xmlDoc.SelectNodes("Settings/Test1/" + strName); 

         foreach (XmlNode node in xmlList) 
         { 
          if (node.FirstChild.Name.ToString() != node.LastChild.Name.ToString()) 
          { 
           foreach (XmlNode childNode in node.ChildNodes) 
           { 
            strDictValues.Add(strName + "." + childNode.LocalName, childNode.InnerText); 
           } 
          } 
          else 
          { 
           strDictValues.Add(strName + "." + node.FirstChild.LocalName, node.InnerText); 
          } 
         } 
         HttpRuntime.Cache.Insert(strName, strDictValues, new System.Web.Caching.CacheDependency(xmlFilePath)); 
        } 
        else 
        { 
         var tmpDict = (Dictionary<string, string>)HttpRuntime.Cache[strName]; 
         foreach (var tmpVal in tmpDict) 
         { 
          strDictValues.Add(tmpVal.Key, tmpVal.Value); 
         } 
        } 

        foreach (var tmpStrDict in strDictValues) 
        { 
         dictValus.Add(tmpStrDict.Key, tmpStrDict.Value); 
        } 
       } 
      } 
     } 
     return dictValus; 
    } 
+0

주셔서 감사합니다. – Jollyguy

관련 문제