C# - 从 DataTable 加载字典

C# - Load Dictionary from DataTable

我需要帮助从 DataTable 读取数据并将键值添加到 Dictionary 对象。

//Here is the object:
public class DBName
{
    public int ID { get; set; }                // key
    public string DatabaseName { get; set; }   // value
}

我的 DataTable 正在获取数据,但不知道如何添加到 Dictionary 阅读 DataTable 并添加到 Dictionary -

public static Dictionary<int,DBName> ReadToDictionary()
{
    string con = @"MyConnectionString;";
    SqlConnection sqlconn = new SqlConnection(con);

    string sqlQuery = @"SELECT DISTINCT DisplayName AS DatabaseName, RANK() OVER(ORDER BY MIN(id)) AS ID
                    FROM dbo.MyTable
                    GROUP BY DisplayName";

    Dictionary<int, DBName> dictionaryDBName = new Dictionary<int, DBName>();
    SqlCommand sqlcmd = new SqlCommand(sqlQuery, sqlconn);
    {
        using (SqlDataAdapter da = new SqlDataAdapter(sqlcmd))
        {
            try
            {
                DataTable dt = new DataTable();
                da.Fill(dt);
                foreach (DataRow dr in dt.Rows)
                {
                    foreach (DataColumn col in dt.Columns)
                    {
                        //how to add key and Value?
                        dictionaryDBName.Add(dr[1], DBName);
                    }
                    // anything here?
                }
            }
            catch (Exception ex)
            {
                //
            }
            finally
            {
                sqlconn.Close();
            }
        }
    }
    return dictionaryDBName;
}

请指导。

只使用 DataReader. 可能会好得多 无需填充 DataTable 然后尝试循环遍历它,只需循环reader.

进一步的观点:

  • 不要吞下异常,妥善处理它们
  • 你需要在连接上有一个using,然后你就不需要调用Close
  • 您知道 RANKDENSE_RANKROW_NUMBER 之间的区别吗?
public static Dictionary<int,DBName> ReadToDictionary()
{
      string con = @"MyConnectionString;";
      using(SqlConnection sqlconn = new SqlConnection(con))
      {
            string sqlQuery = @"SELECT DISTINCT
                                DisplayName AS DatabaseName
                                ,CAST(RANK() OVER(ORDER BY MIN(id)) AS int) AS ID
                            FROM
                                dbo.MyTable
                            GROUP BY 
                                DisplayName";

            sqlconn.Open();
            Dictionary<int, DBName> dictionaryDBName = new Dictionary<int, DBName>();
            using(SqlCommand sqlcmd = new SqlCommand(sqlQuery, sqlconn))
            using (var reader = sqlcmd.ExecuteReader())
            {
                while(reader.Read())
                {
                    DBName n = new DBName { ID = reader.GetInt32(1), DatabaseName = reader[0] as string};
                    dictionaryDBName.Add(n.ID, n);
                }
            }
    
            return dictionaryDBName;
      }
 }

这是 LINQ 解决方案。关键是要使用强大的ToDictionary扩展方法。:

var reader = sqlCmd.ExecuteReader();
var dataTable = new DataTable()
dataTable.Load(reader);
var dictionary = dataTable.Rows.Cast<DataRow>().ToDictionary
( 
    x => (int)x[0],      //Convert column 0 into the dictionary's key
    x => (string)x[1]    //Convert column 1 into the dictionary's value
);
   

但是,由于 SqlDataReader 实现了 IEnumerable,您可以像这样完全跳过数据 table:

var reader = sqlCmd.ExecuteReader();
var dictionary = reader.Cast<IDataRecord>().ToDictionary 
( 
    x => x.GetInt32(0),    //Convert column 0 into the dictionary's key
    x => x.GetString(1)    //Convert column 1 into the dictionary's value
);

另见 this answer