如何使用自己的 DataTable 类“Linq to DataTable”

Posted

技术标签:

【中文标题】如何使用自己的 DataTable 类“Linq to DataTable”【英文标题】:How to "Linq to DataTable" using Own DataTable Class 【发布时间】:2020-12-09 15:49:46 【问题描述】:

我怎样才能把这个 linq 查询产生的任何东西放到我自己的 DataTable 类中?

public class MyDataTable : DataTable

    public MyDataTable()
    
        this.Columns.Add("ColumnName1");
        this.Columns.Add("ColumnName2");
        this.Columns.Add("ColumnName3");
        this.Columns.Add("ColumnName4");
    

我的 linq 查询:

MasterDataTable
.AsEnumerable()
.Where(rr =>
            rr.Field<string>("ColumnName1") == SelectedValue1 &&
            rr.Field<string>("ColumnName2") == SelectedValue2 &&
            rr.Field<string>("ColumnName3") == SelectedValue3 &&
            rr.Field<string>("ColumnName4") == SelectedValue4)
).Select(rr => rr);

我已经尝试过了,但我被警告我无法将 EnumerableRowCollection 转换为 MyDataTable

MyDataTable dt = MasterDataTable
    .AsEnumerable()
    .Where(rr =>
                rr.Field<string>("ColumnName1") == SelectedValue1 &&
                rr.Field<string>("ColumnName2") == SelectedValue2 &&
                rr.Field<string>("ColumnName3") == SelectedValue3 &&
                rr.Field<string>("ColumnName4") == SelectedValue4)
    ).Select(rr => rr);

然后我尝试在 EnumerableRowCollection 中获取所有内容,但在这里我得到“嵌入语句不能是声明或标记语句”

EnumerableRowCollection<DataRow> selection = ConfigurationDataTable
.AsEnumerable()
.Where(rr =>
                rr.Field<string>("ColumnName1") == SelectedValue1 &&
                rr.Field<string>("ColumnName2") == SelectedValue2 &&
                rr.Field<string>("ColumnName3") == SelectedValue3 &&
                rr.Field<string>("ColumnName4") == SelectedValue4)
).Select(rr => rr);

我做错了什么?

【问题讨论】:

MasterDataTable 是否与MyDataTable 具有相同的列,或者是否有其他列未包含在MyDataTable 中?如果是这样,您为什么觉得需要为 MyDataTable 创建自定义类? @pwilcox,是的,MasterDataTable 实际上只是包含所有数据的 MyDataTable 的一个实例。至于你的第二个问题:我实际上也在考虑同样的事情。从本质上讲,我并没有真正做任何特别的事情。我想我可以使用本机 DataTable 类。 【参考方案1】:

我扔掉了自定义类,只对两个数据表使用了本地 DataTable 类。这似乎可以解决问题。

DataTable dt = MasterDataTable
    .AsEnumerable()
    .Where(rr =>
                rr.Field<string>("ColumnName1") == SelectedValue1 &&
                rr.Field<string>("ColumnName2") == SelectedValue2 &&
                rr.Field<string>("ColumnName3") == SelectedValue3 &&
                rr.Field<string>("ColumnName4") == SelectedValue4)
    ).Select(rr => rr)
    .CopyToDataTable();

【讨论】:

很高兴你能弄明白。顺便说一句,你可以完全摆脱Select的使用。【参考方案2】:

DataTable 不继承自 IEnumerable:

https://docs.microsoft.com/en-us/dotnet/api/system.data.datatable.select

您可能最好创建一个继承自 IEnumerable 的自定义类,并创建使用 DataTable 轻松插入数据的方法。

以下是手动读取数据的方法:

// Create your DataTable
var t = new DataTable();
t.Columns.Add("ColumnName1");   // Add your column names
t.Columns.Add("ColumnName2");   // (it is better to use one of the overload
t.Columns.Add("ColumnName3");   //  methods that defines the row's data type
// Create an instance of your new DataRow:
var row = t.NewRow();
// populate your data into your new row:
row["ColumnName1"] = "Bill";
row["ColumnName2"] = "Ted";
row["ColumnName3"] = "Excellent";
// add the DataRow to your DataTable
t.Rows.Add(row);
// Now retrieve the data using something that inherits from IEnumerable
var list = new List<String>();
// Loop through your DataTable to get the individual records
foreach (DataRow row1 in t.Rows) 
    // notice that above you MUST cast the row. It fails if you use "var row".
    list.Add(String.Format("0 1 2", row["ColumnName1"], row["ColumnName2"], row["ColumnName3"]));

// return your IEnumerable item
return list;

我可以给你更好的例子来说明如何使用 DataRow 创建一个 IEnumerable 类对象,但那是很多代码。如果您需要,请告诉我。

【讨论】:

以上是关于如何使用自己的 DataTable 类“Linq to DataTable”的主要内容,如果未能解决你的问题,请参考以下文章

如何计算 LINQ 中 DataTable 的列的总和(到数据集)?

如何在不更改 RowState 属性的情况下使用 LINQ 从数据库中复制 DataTable

C#将LINQ数据集转换为Datatable

如何使用LINQ在具有多个条件的DataTable中的日期之间进行求和?

循环 LINQ 查询并将结果附加到 DataTable

项目中遇到的 linq datatable select