如何使用DataGridView LINQ查询但是表列的子集?

时间:2015-02-20 00:10:15

标签: c# linq datagridview strongly-typed-dataset

我试图从MSDN的代码示例中学习,但我显然不理解LINQ的真正工作原理。我想要做的是为一个“查找窗口”填充一个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',但该表包含我不想向用户显示的列:

where t.SGMTNUMB == 3
select t;

您可以使用一种简单的方法来帮助您使用两个所需的列填充DataGridView吗?如果感觉比使用LINQ更好或更容易,我会接受建议。

2 个答案:

答案 0 :(得分:1)

失败是因为您的select语句正在创建一个包含两个字段的匿名类。它不再是DataRow,编译器也不知道如何通过DataRow将其强制转换回Cast<T>()


一种选择是坚持使用有效的方法,然后只需隐藏您不希望在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();

答案 1 :(得分:0)

扩展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中得到结果,你必须创建一个并逐个添加值。

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;