从Linq查询中选择特定字段并填充DataTable

本文关键字:字段 填充 DataTable Linq 查询 选择 | 更新日期: 2023-09-27 18:01:08

我试图从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
}

从Linq查询中选择特定字段并填充DataTable

您可以尝试这样做,因为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); 
}

//编辑:
我不建议这样做,因为这在很大程度上取决于列的正确顺序,我甚至不确定是否还有其他情况会导致混乱=(从其他解决方案中选择一个(至少在编码方面(

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

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

来自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
}

我会避免此方法的Datatable,并使用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的优点是将数据从与现有事物的关联中分离出来,而是将其引用到只作为集合存在的类中。

您没有很好地描述这个问题。但是,您不应该将行添加到不同的DataTables中,因为通常会出现异常("行已经属于另一个表"(。

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

出于性能原因,我也会使用Enumerable.Join而不是query.Contains

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();