2011-05-30 14 views
5

मैं एक बुनियादी भंडार रूपरेखा है कि अंत में एक प्रश्न निष्पादित करता है और परिणामों को वापस नक्शे एक वस्तु में है के आधार पर एक अनूठा कैश कुंजी जेनरेट डैपर, ऐसा इसलिए है क्योंकि हुड के तहत GetItem डैपर लपेट रहा है।विधि तर्क

  • क्वेरी वाली एक स्ट्रिंग:

    मैं GetItem के लिए स्वत: कैशिंग जोड़ना चाहते हैं, मैं दो तर्क है कि में आते है।

  • किसी भी पैरामीटर युक्त एक अनाम शब्दकोश।

मुझे चिंता है कि इन मानकों पर एक साधारण प्रधानमंत्री हैश कर कैश कुंजी टकराव का कारण होता हूँ, और जब आप एक कैश से डेटा खींच रहे हैं, एक टक्कर बहुत बहुत बुरा हो सकता है (अर्थात संवेदनशील जानकारी लीक)।

तो, मेरे पास कौन सी तकनीकें हैं जो एक उचित आकार की कैश कुंजी उत्पन्न करती हैं, जबकि एक क्वेरी और पैरामीटर के इनपुट के आधार पर विशिष्टता की गारंटी देते हैं?

+0

मेरे लिए यह लगता है कि आप तरह की एक पहचान नक्शे का वर्णन कर रहे हैं। इस मामले में आपकी कुंजी आईडी के साथ मिलकर टाइपहेडल हो सकती है। पहचान मानचित्रों की बात यह है कि आप यह सुनिश्चित करना चाहते हैं कि वे किसी प्रकार के संदर्भ से बंधे हैं, वैश्विक पहचान मानचित्र को अमान्य करना मुश्किल है –

उत्तर

6

मैं प्रतिनिधियों की संचय संस्करण बनाने के लिए निम्नलिखित विस्तार तरीकों का उपयोग:

public static Func<T, TResult> AsCached<T, TResult>(this Func<T, TResult> function) 
    { 
     var cachedResults = new Dictionary<T, TResult>(); 
     return (argument) => 
     { 
      TResult result; 
      lock (cachedResults) 
      { 
       if (!cachedResults.TryGetValue(argument, out result)) 
       { 
        result = function(argument); 
        cachedResults.Add(argument, result); 
       } 
      } 
      return result; 
     }; 
    } 

    public static Func<T1, T2, TResult> AsCached<T1, T2, TResult>(this Func<T1, T2, TResult> function) 
    { 
     var cachedResults = new Dictionary<Tuple<T1, T2>, TResult>(); 
     return (value1, value2) => 
     { 
      TResult result; 
      var paramsTuple = new Tuple<T1, T2>(value1, value2); 
      lock(cachedResults) 
      { 
       if (!cachedResults.TryGetValue(paramsTuple, out result)) 
       { 
        result = function(value1, value2); 
        cachedResults.Add(paramsTuple, result); 
       } 
      } 
      return result; 
     }; 
    } 

    public static Func<T1, T2, T3, TResult> AsCached<T1, T2, T3, TResult>(this Func<T1, T2, T3, TResult> function) 
    { 
     var cachedResults = new Dictionary<Tuple<T1, T2, T3>, TResult>(); 
     return (value1, value2, value3) => 
     { 
      TResult result; 
      var paramsTuple = new Tuple<T1, T2, T3>(value1, value2, value3); 
      lock(cachedResults) 
      { 
       if (!cachedResults.TryGetValue(paramsTuple, out result)) 
       { 
        result = function(value1, value2, value3); 
        cachedResults.Add(paramsTuple, result); 
       } 
      } 
      return result; 
     }; 
    } 

और इसी तरह एन मापदंडों के लिए ...

मामले में यह कोड से स्पष्ट नहीं है, मैं तर्कों के साथ एक tuple बनाएँ, और tuple का उपयोग एक शब्दकोश के लिए एक कुंजी के रूप में करें जो तर्क के प्रत्येक सेट के लिए वापसी मूल्य रखता है। ध्यान दें कि हर बार जब आप AsCached पर कॉल करते हैं, तो आप एक अलग कैश बनाते हैं।

आप इस प्रकार इन तरीकों का उपयोग कर सकते हैं:

private Func<int, SomeEntity> _getCached; 

public SomeEntity Get(int id) 
{ 
    if (_getCached == null) 
    { 
     Func<int, SomeEntity> func = GetImpl; 
     _getCached = func.AsCached(); 
    } 
    return _getCached(id); 
} 

private SomeEntity GetImpl(int id) 
{ 
    return base.GetItem<SomeEntity> 
       ("select * from SomeEntities where id = @idParam", 
       new { idParam = id}); 
} 
2

मैं किसी कक्षा के लिए कुछ विकल्प

  1. पैक डेटा देखने, वर्ग को क्रमानुसार और आप एक हैश कुंजी देने के लिए करने के लिए धारावाहिक डेटा पर एक SHA1 हैश प्रदर्शन करने के लिए एक BinaryFormatter का उपयोग करें।

  2. एक वर्ग में डेटा पैक करें, IEqualityComparer को लागू करें जिसे बाद में एक शब्दकोश में संग्रहीत किया जा सकता है। IEqualityComparer को लागू करके आप हैश की पीढ़ी को नियंत्रित करेंगे और डेटा तुलना की तुलना में अद्वितीय डेटा की पहचान करने के लिए किया जाएगा।

संबंधित मुद्दे