如何将 LINQ 查询与 DataGridView 但 table 列的子集一起使用?

How to use LINQ query with DataGridView but a subset of table columns?

我正在尝试从 MSDN 的代码示例中学习,但我显然不了解 LINQ 的真正工作原理。我想要做的是使用来自强类型数据集的 table 中可用列的子集填充 "lookup window" 的 DataGridView。我正在尝试以下操作:

IEnumerable<DataRow> query = 
            (from t in DataAccess.ds.GL40200.AsEnumerable()
            where t.SGMTNUMB == 3 
            select new { t.SGMNTID, t.DSCRIPTN });

DataTable myTable = query.CopyToDataTable<DataRow>();

dgv_Exhibitors.DataSource = myTable;

然而,这会抱怨从 EnumerableRowCollection<AnonymousType#1>IEnumerable<System.Data.DataRow> 的隐式转换错误。

我尝试添加以下内容,但会导致运行时错误:

select new { t.SGMNTID, t.DSCRIPTN }).Cast<DataRow>();

虽然仅选择 't' 有效,但 table 包含我不想向用户显示的列:

where t.SGMTNUMB == 3
select t;

您能否提供一种仅使用所需的两个列填充 DataGridView 的简单方法?如果有比使用 LINQ 更好或更简单的方法,我愿意接受建议。

它失败了,因为您的 select 语句正在创建一个匿名的 class,其中有两个字段。它不再是 DataRow,编译器也不知道如何通过 Cast<T>().

将它转换回 DataRow

一个选择是坚持使用有效的方法,然后简单地隐藏您不想在 DataGridView:

中看到的列
dgv_Exhibitors.DataSource =
    DataAccess.ds.GL40200.AsEnumerable().Where(t => t.SGMTNUMB == 3).CopyToDataTable();

foreach (var col in dgv_Exhibitors.Columns.Cast<DataGridViewColumn>()
                                  .Where(c => c.Name != "SGMNTID" && c.Name != "DSCRIPTN"))
{
    col.Visible = false;
}

或者,设置 AutoGenerateColumns = false,然后只定义您要查看的列并将它们添加到 DataGridView.Columns 集合。


另一种选择是使用您现有的方法,但对其调用 ToList(),不要费心尝试将其转换回 DataTableDataGridView可以显示任意集合:

dgv_Exhibitors.DataSource = (from t in DataAccess.ds.GL40200.AsEnumerable()
                             where t.SGMTNUMB == 3 
                             select new { t.SGMNTID, t.DSCRIPTN }).ToList();

扩展 Grant Winney 的回答,使用 var 而不是 IEnumerable <DataRow> 来接收匿名类型。

var query = 
        (from t in DataAccess.ds.GL40200.AsEnumerable()
        where t.SGMTNUMB == 3 
        select new { t.SGMNTID, t.DSCRIPTN });

如果您想要数据表中的结果,则必须创建一个数据表并逐一添加值。

DataTable myTable = new DataTable();
myTable.Columns.Add("SGMNTID", typeof(int));
myTable.Columns.Add("DSCRIPTN", typeof(string));
foreach (var x in query)
        {
            DataRow dr = myTable.NewRow();
            dr[0] = x.SGMNTID;
            dr[1] = x.DSCRIPTN;
            myTable.Rows.Add(dr);
        }

dgv_Exhibitors.DataSource = myTable;