【问题标题】:C# Add column in datatable from databaseC#从数据库的数据表中添加列
【发布时间】:2017-08-29 16:46:58
【问题描述】:

我有一个来自存储过程的数据表。我想添加一个名为“Assessment”的列,该列将从 sql 查询中填充。最后我想用这个数据表填充一个商店。在 Visual Studio 中,我看到包含“SiteId”的数据表列名为 7。但我收到此错误:

加载失败:列“7”不属于表。

和代码:

DAL.DBDataContext dc = new DAL.DBDataContext();
try
{
    SqlConnection sqlConnection1 = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DBConnectionString"].ConnectionString);
    SqlCommand cmd = new SqlCommand();
    SqlDataReader sqlreader;

    cmd.CommandText = "StorProc";
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Add(new SqlParameter("@CTid", ctid));

    cmd.Connection = sqlConnection1;
    sqlConnection1.Open();
    sqlreader = cmd.ExecuteReader();

    var dt = new DataTable();
    dt.Load(sqlreader);

    //Add assessment column
    dt.Columns.Add("Assessment", typeof(System.String));

    var data = new List<object>();
    foreach (DataRow r in dt.Rows)
    {
        if (r[7] != null)
        {
            var res = (from d in dc.Doctors
                       join ct in dc.CTUsers on d.id equals ct.DoctorId
                       where ct.CTid == ctid && ct.SiteId == Int32.Parse(r["7"].ToString())
                       select d).FirstOrDefault();
            r["Assessment"] = res.Assessment;
        }                     
        data.Add(r);
    }

    this.storeSites.DataSource = dt;
    this.storeSites.DataBind();
    sqlConnection1.Close();
}
catch (Exception a)
{
    X.Msg.Alert("Warning", "Load failed:" + a.Message).Show();
}

【问题讨论】:

  • r[6] 或 r[8] 有效吗?列名是7 似乎很奇怪。
  • 如果我在 sql server 中运行存储过程,则会出现“id”等列名。但是如果我在 Visual Studio 中打开 ItemArray of r,我只会看到数字。检查上传的照片
  • 基本上,Int32.Parse(r["7"].ToString() 是你的问题,我相信。

标签: c# mysql datatable


【解决方案1】:

DataRow class 有一个重载的索引器来访问列。

public object this[int columnIndex] { get; set; }

... 通过其int 索引访问该列(这是我们可以在您的图像上看到的)。你通过传递一个int来使用它:

object o = r[7];   // NOT r["7"] !

另一个重载

public object this[string columnName] { get; set; }

... 需要以string 形式传递的列名:

object o = r["Assessment"];

如果该列确实命名“7”,那么您必须像这样访问它:

object o = r["7"];  // But this is wrong in your case!

请注意,传递给索引的参数类型会有所不同。所以r[7]r["Assessment"] 都适用于你的情况。首选使用名称,因为如果架构或查询更改,索引可能会更改。 r["7"] 不起作用,因为没有这样命名的列。

见:

【讨论】:

    【解决方案2】:

    请试试这个:

    foreach (DataRow r in dt.Rows)
    {
      foreach(DataColumn column in dt.Columns)
      {
        if (r[column] != null && r[column].ColumnName == "some column name")
        {
         var res = (from d in dc.Doctors
         join ct in dc.CTUsers on d.id equals ct.DoctorId
         where ct.CTid == ctid && ct.SiteId == Int32.Parse(r[column].ToString())
         select d).FirstOrDefault();
         r["Assessment"] = res.Assessment;
        }                     
      }
      data.Add(r);
    }
    

    Int32.Parse(r["7"].ToString() 不正确。您正在请求名为 7 的列。

    我觉得上面的代码比较清晰。

    编辑

    您还可以像这样访问行列值:

    r.ItemArray[i].ToString()

    像这样:

    for (int i = 0; i < dt.Rows.Count; i++)
    {
      var r = dt.Rows[i];
      var value = r.ItemArray[7].ToString();
        if (!String.IsNullOrEmpty(value))
        {
         var res = (from d in dc.Doctors
         join ct in dc.CTUsers on d.id equals ct.DoctorId
         where ct.CTid == ctid && ct.SiteId == Int32.Parse(value)
         select d).FirstOrDefault();
         r["Assessment"] = res.Assessment;
        }   
      data.Add(r);
    }
    

    【讨论】:

    • 但是使用这种方法,它会检查所有列以找到等于 ct.SiteId 的值,对吧?我只想检查一个特定的,以避免任何错误
    • 我明白了。你不能添加到 if 语句吗? r[column] != null &amp;&amp; r[column].ColumnName == "some column name"?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-24
    • 2014-07-23
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    • 2014-12-27
    相关资源
    最近更新 更多