You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# DataGridView联表查询后获取选中行值报主键缺失错误求助

解决联表查询后DataTable无主键导致的Rows.Find报错问题

问题原因

虽然Assignment表本身定义了主键,但使用多表联合查询后,数据库返回的结果集是多表组合结构,不会向SqlDataAdapter传递主键元数据;同时FillSchema无法自动识别多表结果集的主键,导致DataSet中的Assignment表PrimaryKey属性为空,调用Rows.Find时就会抛出MissingPrimaryKeyException。


解决方案

1. 手动为DataTable设置主键

在填充数据完成后,强制指定AssignmentID列为DataTable的主键,代码修改如下:

daAssignmentDue.Fill(dsStudentManagementSystem, "Assignment");
// 手动设置主键
DataTable assignmentTable = dsStudentManagementSystem.Tables["Assignment"];
assignmentTable.PrimaryKey = new DataColumn[] { assignmentTable.Columns["AssignmentID"] };

// 后续绑定DataGridView的代码不变
dgvAssignmentsDue.DataSource = dsStudentManagementSystem.Tables["Assignment"];
dgvAssignmentsDue.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
dgvAssignmentsDue.Refresh();

此方法直接绕过自动识别主键的问题,确保Rows.Find能正常通过主键值查找行。

2. 移除无效的FillSchema调用(可选)

联表场景下FillSchema无法获取有效主键信息,反而多一次数据库请求,可以直接移除该调用,只保留Fill操作即可,不影响功能。


重要修复:SQL注入漏洞

当前代码使用字符串拼接学生ID,存在严重的SQL注入风险,必须改为参数化查询:

// 改写SQL,使用参数占位符
sqlAssignmentDue = @"SELECT a.AssignmentID, a.AssignmentName AS Name, a.ReleaseDate AS Released, a.DueDate AS Due, a.Submitted, a.Score,
asD.ModuleCode,
aStu.StudentID
 FROM Assignment a
 JOIN AssignmentDetails asD ON a.AssignmentID = asd.AssignmentID
 LEFT JOIN AssignmentStudents aStu ON a.AssignmentID = aStu.AssignmentID
 WHERE aStu.StudentID = @StudentID AND a.Submitted = 0"; // BIT类型用数值0代替字符串'false'更稳妥

daAssignmentDue = new SqlDataAdapter(sqlAssignmentDue, connStr);
// 添加参数,避免SQL注入
daAssignmentDue.SelectCommand.Parameters.AddWithValue("@StudentID", txtGradeStudentID.Text);

// 后续填充数据的代码不变

参数化查询不仅能避免注入攻击,还能避免因特殊字符(如单引号)导致的SQL语法错误。


内容的提问来源于stack exchange,提问作者Sean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:42:50