使用 Linq 循环访问 DataGridView 的子集时出现对象引用错误



>编辑:我了解 NRE 的基础知识,我不明白此 LINQ 查询和我的 datagridview 发生此情况的确切原因。我看到必须小心使用"新行",但我尝试了三种不同的方法来调整它 - 在两种情况下使用 IsNewRow,并尝试将where grid.Index != dgv_Exhibitors.NewRowIndex作为第三种情况。请帮助我了解为什么会发生这种情况以及如何纠正它,而不仅仅是将其视为重复项。

我有代码将 DataGridView 中的列与 DataTable 中的列进行比较。目的是查找并突出显示数据表中不存在的单元格。但是,更改单元格颜色后,我收到对象引用错误。

private void ValidateData()
{
    DataTable dtSubs = Controller.Instance.GetSubaccounts();
    var entriesNotInSubs =
        dt.AsEnumerable().Select(r => r.Field<string>("EXHIBITOR").Trim()).Except(dtSubs.AsEnumerable().Select(r => r.Field<string>("SGMNTID").Trim()));
    var invalidExhibitors =
        from grid in dgv_Exhibitors.Rows.OfType<DataGridViewRow>()
        join segment in entriesNotInSubs on grid.Cells["EXHIBITOR"].Value.ToString().Trim() equals segment.Trim()
        select grid;
    foreach (var row in invalidExhibitors)
    {
        row.Cells["EXHIBITOR"].Style.BackColor = Color.Red;
    }
}

我不太确定如何解释错误信息,除了错误发生在 MoveNext() 上,但哪一行是问题所在?谢谢你的时间。

System.NullReferenceException: Object reference not set to an instance of an object. 
at VirtualPrintFeesGPAddin.ExhibitorMaint.<ValidateData>b__6(DataGridViewRow grid) 
at System.Linq.Enumerable.<JoinIterator>d__61`4.MoveNext()    
at VirtualPrintFeesGPAddin.ExhibitorMaint.ValidateData() 
at VirtualPrintFeesGPAddin.ExhibitorMaint.btnValidate_Click(Object sender, EventArgs e)

更新:我已经完成了以下操作,并且出现与未检查IsNewRow属性完全相同的错误。

foreach (var row in invalidExhibitors)
{
    if (row.IsNewRow == false)
        row.Cells["EXHIBITOR"].Style.BackColor = Color.Red;
}

更新2:我也因此对其进行了测试:

from grid in dgv_Exhibitors.Rows.OfType<DataGridViewRow>()
join segment in entriesNotInSubs on grid.Cells["EXHIBITOR"].Value.ToString().Trim() equals segment.Trim()
where grid.IsNewRow == false 
select grid;

它提供了略有不同的错误信息:

at System.Linq.Enumerable.<JoinIterator>d__61`4.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()

经过多次重写,我找到了一个解决方案,我认为它会像所有其他解决方案一样失败,但令我惊讶的是,使用两个 Where 子句终于奏效了。

var entriesNotInSubs =
    dt.AsEnumerable().Select(r => r.Field<string>("EXHIBITOR").Trim()).Except(dtSubs.AsEnumerable().Select(r => r.Field<string>("SGMNTID").Trim()));
var dgvRow_ExhibitorNotInSubs =
    (from exibitors in dgv_Exhibitors.Rows.OfType<DataGridViewRow>()
    select exibitors)
        .Where(j => j.IsNewRow == false)
        .Where(i => entriesNotInSubs.Contains(i.Cells[0].Value.ToString().Trim()));
foreach (var row in dgvRow_ExhibitorNotInSubs)
{
    row.Cells[0].Style.BackColor = Color.OrangeRed;
}

最新更新