2009-02-12 3 views
0

В настоящее время в моих приложениях ASP.Net web.config У меня есть параметр приложения, в котором хранится список значений сопоставления с разделителями-запятыми, как показано ниже. В коде, который мне нужен, нужно выполнить поиск этих данных на основе входных значений 1, 2, 3 и т. Д. Я могу либо разбить его, либо закольцовать до тех пор, пока не найду совпадение, или не воспользуюсь Regex, чтобы вывести значение из строки конфигурации.ASP.Net Mapping Values ​​Lookup

В настоящее время я использую Regex для получения значения отображения. Я не возражаю против изменения способа хранения данных в файле web.config. Есть ли более простой и элегантный способ справиться с этим?

<add key="Mappings" value="1|APP,2|TRG,3|KPK,4|KWT,5|CUT" /> 

ответ

1

Если вам нужно использовать этот поиск часто и строка в файле web.config не меняется очень часто, то это имеет смысл разобрать строку один раз в объект Dictionary и сохранить ее в приложении или кеше.

Поиск в Словаре будет молниеносно, особенно по сравнению с разбором строки каждый раз.

private static readonly object _MappingsLock = new object(); 

public static string GetMapping(int id) 
{ 
    // lock to avoid race conditions 
    lock (_MappingsLock) 
    { 
     // try to get the dictionary from the application object 
     Dictionary<int, string> mappingsDictionary = 
      (Dictionary<int, string>)Application["MappingsDictionary"]; 

     if (mappingsDictionary == null) 
     { 
      // the dictionary wasn't found in the application object 
      // so we'll create it from the string in web.config 
      mappingsDictionary = new Dictionary<int, string>(); 

      foreach (string s in mappingsStringFromWebConfig.Split(',')) 
      { 
       string[] a = s.Split('|'); 
       mappingsDictionary.Add(int.Parse(a[0]), a[1]); 
      } 

      // store the dictionary in the application object 
      // next time around we won't need to recreate it 
      Application["MappingsDictionary"] = mappingsDictionary; 
     } 

     // now do the lookup in the dictionary 
     return mappingsDictionary[id]; 
    } 
} 

// eg, get the mapping for id 4 
string mapping = GetMapping(4); // returns "KWT" 
+0

Да, я знаю, что там есть потенциальное состояние гонки, и обработка исключений не является, но это просто код с концептуальной концепцией;) – LukeH

+0

Итак, чтобы обработать условие гонки, вы бы бросили оператор блокировки вокруг части, которая добавляет к кэш? – James

+0

@James, Это именно то, что я сделал бы. Я обновлю код примера. – LukeH

0

Разделить строку на запятые, то каждая подстрока на |, хранить их в словарь и найти его с помощью клавиши.

Это как альтернатива регулярному выражению. Вы знаете, что они говорят о Regex.

+0

Нет, на самом деле я не знаю, что они говорят о Regex. Разве это не хорошая идея использовать его для этого? Я думаю, что Regex будет лучшим решением, так как никакие массивы не должны быть инициализированы. – James

+0

Это была какая-то шутка. цитата, которую я видел здесь, здесь: «Когда вы решаете проблему с помощью Regex, теперь у вас есть две проблемы». Версия Regex, вероятно, является более элегантным решением, но если скорость является проблемой, вы можете кэшировать строку web.config, а также словарь. – Moose

+0

Затем, когда у вас есть другой запрос для поиска, сравните кешированную строку с строкой web.config, если она другая, перестройте словарь. Если у вас нет * огромного * набора, я не думаю, что производительность действительно будет проблемой в любом случае. – Moose

1

Просто интересно :) А как насчет LINQ

string inputValue = "2"; 
string fromConfig = "1|APP,2|TRG,3|KPK,4|KWT,5|CUT";    
string result = fromConfig 
    .Split(',') 
    .Where(s => s.StartsWith(inputValue)) 
    .Select(s => s.Split('|')[1]) 
    .FirstOrDefault(); 

Или

Regex parseRegex = new Regex(@"((?<Key>\d)\|(?<Value>\S{3}),?)"); 
parseRegex.Matches(fromConfig) 
    .Cast<Match>() 
    .Where(m => m.Groups["Key"].Value == inputValue) 
    .Select(m => m.Groups["Value"].Value) 
    .FirstOrDefault();