【问题标题】:Select specific fields from Linq query and populate a DataTable从 Linq 查询中选择特定字段并填充 DataTable
【发布时间】:2013-02-26 16:30:25
【问题描述】:

我正在尝试从 Linq 查询中选择一个仅包含指定字段的数字 DataRows,然后使用这些 DataRows 填充 DataTable。问题是,当我将这些 DataRows 添加到新的 DataTable 时,我希望 ID 和 Name 字段都被分别填充。但是,DataTable 中的 ID 字段同时包含 ID 和 Name 值。有人可以指出我做错了什么。

代码如下:

var query2 = from s in Tables[Table_Sec].AsEnumerable()
             where query.Contains(s["sectype"])
             select new { id = s["id"], name = s["name"] }; // I only want these fields



DataTable dt = new DataTable();  // Create my new dataTable
dt.Columns.Add("id", typeof(string));
dt.Columns.Add("name", typeof(string));

foreach(var row in query2)
{
  dt.Rows.Add(row);  // ID field contains both ID and Name strings. Name field contains nothing
}

【问题讨论】:

  • 出了什么问题?你能更清楚地描述问题,你有例外吗? query 是什么?

标签: c# linq


【解决方案1】:

你可以试试这个,因为 DataRow 构造函数允许你传递一个对象数组

var result = from s in Tables[Table_Sec].AsEnumerable()
             where query.Contains(s["sectype"])
             select new object[] 
             {
                 s["id"],
                 s["name" ]
             };

DataTable dt = new DataTable();  
dt.Columns.Add("id", typeof(string));
dt.Columns.Add("name", typeof(string));

foreach(var row in result)
{
    dt.Rows.Add(row); 
}

// 编辑:
我不会推荐这种方式,因为它在很大程度上取决于列的正确顺序,我什至不确定是否还有其他情况会导致混乱=)从其他解决方案中选择一个(至少用于编码)

【讨论】:

    【解决方案2】:

    您必须手动填充一行中的每个单元格:

    foreach(var row in query2)
    {
        var newRow = dt.NewRow();
        newRow["id"]= row.id;
        newRow["name"]= row.name;
        dt.Rows.Add(newRow);
    }
    

    【讨论】:

      【解决方案3】:

      来自MSDN

      DataRow newCustomersRow = dataSet1.Tables["Customers"].NewRow();
      
      newCustomersRow["CustomerID"] = "ALFKI";
      newCustomersRow["CompanyName"] = "Alfreds Futterkiste";
      
      dataSet1.Tables["Customers"].Rows.Add(newCustomersRow);
      

      这是向数据表添加行的方式

      所以你的会是这样的:

      foreach(var row in query2)
      {
      var newRow = dt.NewRow();
      newRow["id"] = row.id;
      newRow["name"] = row.name;
        dt.Rows.Add(newRow);  // ID field contains both ID and Name strings. Name field contains nothing
      }
      

      【讨论】:

        【解决方案4】:

        我会避免使用此方法的数据表并使用 POCO,Plain Old Class Object。

        public class POCO
        {
             public string id { get; set; }
             public string name { get; set; }
        }
        
        var query2 = from s in Tables[Table_Sec].AsEnumerable()
                     where query.Contains(s["sectype"])
                     select new POCO { id = s["id"], name = s["name"] };
        

        POCO 的优点是您将数据与现有事物的关联分开,而是将其引用到仅作为集合而存在的类。

        【讨论】:

          【解决方案5】:

          您没有很好地描述问题。但是,您不应将行添加到不同的DataTables,因为您通常会遇到异常(“行已属于另一个表”)。

          您应该使用强类型字段扩展方法,以确保您在选择对象时不会错误地使用ReferenceEquals。当 Linq 查询包含 IEnumerable<DataRow> 时,您可以使用 CopyToDataTable 创建一个新的 DataTable

          我也会使用Enumerable.Join 而不是query.Contains for performance reasons

          var query2 = from secRow in Tables[Table_Sec].AsEnumerable()
                       join sectype in query on secRow.Field<string>("sectype") equals sectype 
                       select secRow;
          
          DataTable dt = query2.CopyToDataTable();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-12-07
            • 2010-09-05
            • 1970-01-01
            • 1970-01-01
            • 2020-04-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多