迭代数据库表行并在Dictionary中存储值?

时间:2016-06-28 11:19:20

标签: c# performance linq caching .net-4.5

我想在我的程序中实现一个字典缓存。如何将下图中显示的数据库结果存储在字典集合中?

我想迭代数据库表并将LanguageName和IsoCode列的内容存储在像这样Dictionary<LanguageName,IsoCode>的字典中。

我的数据库(ctlang)如下所示:
enter image description here

这是我的代码:

private string GetLanguageForIsoCode(string isoCode)
    {

        //check the isocode column and return the corresponding language
        using (var unitOfWork = dataAccessUnitOfWorkFactory.Create())
        {   
            //need to call every time the sql query
            string query = "SELECT languagename FROM ctlang WHERE isocode='" + isoCode + "'";
            List<string> result = unitOfWork.OwEntities.Database.SqlQuery<string>(query).ToList();

            if (result.FirstOrDefault() != null)
            {
                return result.FirstOrDefault();
            }

            //if language not available in Database, fallback to German as default language
            Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("de");
            //displayName = Deutsch
            return CultureInfo.GetCultureInfo("de").NativeName;
        }
    }

奖金问题:如何使用值搜索字典中的密钥?

2 个答案:

答案 0 :(得分:1)

是的。通过其值返回密钥没有问题,唯一的问题是理论上可能是多于一个分配给该值的密钥,因为密钥是重要的。但是在特定的情况下应该没有问题,因为只有一个isocode代表一种语言。因此,使用字典来实现它就没有问题了:

public Dictionary<string, string> languagesAndKeys = new Dictionary<string, string>();  //Create it

然后你可以搜索那样的键/值:

string myValueByKey = languagesAndKeys["myKey"]; //getting value by key is easy
string myKeyByValue = languagesAndKeys.FirstOrDefault(item => item.Value == "myValue").Key; //getting the key of the FIRST matching value/or returning the default type. You'll need a check to be sure.

之后,您可以轻松地将sql表中的数据加载到字典中。为了实现这个目标,您可以使用带有dataadapter的临时数据表,只要表不是那么大就可以正常运行,或者您可以使用DataReader逐个循环遍历sql表中的行。我将使用临时DataTable:

string cmdText = "SELECT * FROM ctlang";    //As far as I saw your cmd text in the code example, you may still want to take a look tho
string connectionString = "";   //fill the connection string according to your SQL server data
SqlDataAdapter dataAdapter = new SqlDataAdapter(cmdText, connectionString);
DataTable dTable = new DataTable();
dataAdapter.Fill(dTable);

foreach(DataRow row in dTable.Rows)
    languagesAndKeys.Add(row[1].ToString(), row[0].ToString());//second column as a key, first column as a value - just like the structure of your table.

答案 1 :(得分:0)

这就是我解决问题的方法。在我的数据库中,带有语言的表名为CTLANG,列为LANGUAGENAME和ISOCODE。我想将这些映射到Dictionary集合中。所以最后字典看起来像这样:[“LanguageName”,“IsoCode”]。

 private static Dictionary<string, string> languageToIsoCode; //dictionary cache
 private void InitializeLanguageCacheDictionary()
    {
        using (var unitOfWork = dataAccessUnitOfWorkFactory.Create())
        {
            languageToIsoCode = (from p in unitOfWork.OwEntities.CTLANG
                                 select new {p.LANGUAGENAME, p.ISOCODE}).ToDictionary(p => p.LANGUAGENAME, p => p.ISOCODE);
        }
    }

感谢@ D.Petrov,我还找到了一种在字典中搜索密钥并将其值重新给出的方法。

这就是我优化方法以使用字典缓存的方法。

private string GetLanguageForIsoCode(string isoCode)
    {
        if (languageToIsoCode == null)//if cache empty initialize it
        {
            InitializeLanguageCacheDictionary();
        }

        //searches inside the dictionary, look for value and then return key
        //might be bad if there are more than one value asigned to a key
        //because value does not habe to be unique
        string languageFromIsoCodeFromCache = languageToIsoCode.FirstOrDefault(item => item.Value == isoCode).Key;

        if (languageFromIsoCodeFromCache == null)
        {
            //fallback and use the German language as default
            return CultureInfo.GetCultureInfo("de").NativeName;
        }

        return languageFromIsoCodeFromCache;
    }