C# 在数据库表行上迭代并在字典中存储值?
我想在我的程序中实现字典缓存。如何将下图中显示的数据库结果存储到字典集合中 我想遍历数据库表,并将LanguageName和IsoCode列的内容存储在一个字典中,就像这样C# 在数据库表行上迭代并在字典中存储值?,c#,performance,linq,caching,.net-4.5,C#,Performance,Linq,Caching,.net 4.5,我想在我的程序中实现字典缓存。如何将下图中显示的数据库结果存储到字典集合中 我想遍历数据库表,并将LanguageName和IsoCode列的内容存储在一个字典中,就像这样字典 我的数据库(ctlang)如下所示: 这是我的密码: private string GetLanguageForIsoCode(string isoCode) { //check the isocode column and return the corresponding language
字典
我的数据库(ctlang)如下所示:这是我的密码:
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;
}
}
私有字符串GetLanguageForIsoCode(字符串isoCode)
{
//检查等码列并返回相应的语言
使用(var unitOfWork=dataAccessUnitOfWorkFactory.Create())
{
//需要在每次sql查询时调用
string query=“从ctlang中选择languagename,其中isocode=”+isocode+”;
List result=unitOfWork.OwEntities.Database.SqlQuery(query.ToList();
if(result.FirstOrDefault()!=null)
{
返回结果。FirstOrDefault();
}
//如果数据库中没有可用的语言,请回退到德语作为默认语言
Thread.CurrentThread.CurrentCulture=CultureInfo.GetCultureInfo(“de”);
//displayName=Deutsch
返回CultureInfo.GetCultureInfo(“de”).NativeName;
}
}
附加问题:如何使用该值在字典中搜索关键字?确实如此。按键的值返回键没有问题,唯一的问题是理论上可能会有多个键分配给该值,因为键才是最重要的。但在您的特殊情况下,这应该没有问题,因为只有一个等位码代表一种语言。因此,使用字典,这样做是没有问题的:
public Dictionary<string, string> languagesAndKeys = new Dictionary<string, string>(); //Create it
之后,您可以轻松地将数据从sql表加载到字典中。为此,您可以使用带有dataadapter的临时datatable,只要表不是那么大,它就可以正常工作,或者可以使用DataReader逐个循环sql表中的行。我将使用一个临时数据表:
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.
这就是我解决问题的方法。在我的数据库中,包含这些语言的表名为CTLANG,列名为LANGUAGENAME和ISOCODE。我想把这些映射到一个字典集合中。因此,字典的结尾是这样的:[“LanguageName”,“IsoCode”]
但是,如何从数据库中向字典集合添加语言和等码?我知道如何创建字典集合,但很难用数据库值实例化它。@Devid我已经用一个示例方法更新了答案,说明了如何使用临时数据表填充字典。还有其他方法,但由于您的表没有那么大,这也没问题。myKeyByValue对我帮助很大。谢谢+1@Devid事实上,它在互联网上全面存在,所以没问题:我希望您已经了解了如何使用sql表来维护数据。如果有什么不清楚的地方,如果我能进一步提供帮助,我会很高兴。如果我能得到-1的原因,那就太好了,然后我可以改进我的问题。您的查询中有一个非常好的SQL注入。
isoCode=“”;DROP TABLE ctlang;”
@matthewhited如果你看下面的答案,我用实体框架解决了SQL注入问题。希望能让你快乐;)
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.
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);
}
}
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;
}