【问题标题】:ASP.Net Mapping Values LookupASP.Net 映射值查找
【发布时间】:2009-02-12 23:45:00
【问题描述】:

目前在我的 ASP.Net 应用程序 web.config 中,我有一个应用程序设置,用于存储以逗号分隔的映射值列表,如下所示。在后面的代码中,我需要根据输入值 1、2、3 等对此数据执行查找。我可以对其进行字符串拆分并循环,直到找到匹配项,或者使用正则表达式从配置字符串中提取值。

目前我正在使用正则表达式来获取映射值。我不反对更改数据在 web.config 中的存储方式。有没有更简单优雅的处理方式?

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

【问题讨论】:

    标签: asp.net regex parsing web-config lookup


    【解决方案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"
    

    【讨论】:

    • 是的,我知道其中存在潜在的竞争条件,并且没有异常处理,但这只是概念验证代码;)
    • 所以要处理竞争条件,你会在添加到缓存的部分周围抛出一个锁定语句吗?
    • @James,这正是我要做的。我将更新示例代码。
    【解决方案2】:

    只是好奇 :) 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();
    

    【讨论】:

      【解决方案3】:

      用逗号分割字符串,然后用|分割每个子字符串,将它们存储在字典中并按键查找。

      这只是作为 Regex 的替代品。你知道他们对 Regex 的评价。

      【讨论】:

      • 不,实际上我不知道他们对 Regex 的评价。用它来做这个不是一个好主意吗?我认为 Regex 将是性能最好的解决方案,因为不需要初始化数组。
      • 这是个笑话。我在这里看到的引用是“当你使用正则表达式解决问题时,现在你有两个问题。”正则表达式版本可能是一个更优雅的解决方案,但如果速度是一个问题,您可以缓存 web.config 字符串以及字典。
      • 然后,当您有另一个查找请求时,将缓存的字符串与 web.config 字符串进行比较,如果不同,则重建字典。除非你有一个 huge 集合,否则我认为无论哪种方式性能都不会成为问题。
      猜你喜欢
      • 2011-05-14
      • 1970-01-01
      • 2010-10-08
      • 2011-03-25
      • 1970-01-01
      • 2019-07-23
      • 1970-01-01
      • 2012-01-08
      • 2014-08-19
      相关资源
      最近更新 更多