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

GridView展示Active Directory用户报“该行已属于此表”错误如何解决

错误根因
  • 核心问题是DataRow dr = dt.NewRow();的初始化逻辑放在了foreach循环外部,全程复用同一个DataRow实例:第一次将dr添加到DataTable的行集合后,该实例就已经和当前DataTable绑定,后续循环再次尝试添加同一个实例时,就会触发This row already belongs to this table报错。
修复方案

将DataRow的创建逻辑移动到foreach循环内部,每次循环生成全新的行对象,同时补充可空类型判空、资源释放的优化逻辑,修复后代码如下:

DirectoryEntry objDirEntry = new DirectoryEntry(strADPath, strUsername, strPassword);
PrincipalContext ctx = new PrincipalContext(ContextType.Domain, strADPath, strUsername, strPassword);
UserPrincipal usr = new UserPrincipal(ctx);
// 用using包裹自动释放查询资源
using (PrincipalSearcher ps = new PrincipalSearcher(usr))
{
    PrincipalSearchResult<Principal> results = ps.FindAll();
    DataTable dt = new DataTable();
    dt.Columns.Add("First Name");
    dt.Columns.Add("Last Name");
    dt.Columns.Add("Last Logon");
    dt.Columns.Add("Last Password Reset");

    foreach (UserPrincipal u in results)
    {
        // 每次循环创建新的行对象
        DataRow dr = dt.NewRow();
        dr["First Name"] = u.DisplayName ?? string.Empty;
        dr["Last Name"] = u.SamAccountName ?? string.Empty;
        // 可空类型判空,避免空引用异常
        dr["Last Logon"] = u.LastLogon?.ToString() ?? "无记录";
        dr["Last Password Reset"] = u.LastPasswordSet?.ToString() ?? "无记录";
        dt.Rows.Add(dr);
    }
    grdViewAllADSUsers.DataSource = dt;
    grdViewAllADSUsers.DataBind();
}
catch (Exception ex)
{
    error.Text = ex.Message;
}
额外注意事项
  • PrincipalSearcher实现了IDisposable接口,使用using包裹可以自动释放非托管AD查询资源,避免内存泄漏。
  • UserPrincipal的LastLogon、LastPasswordSet、DisplayName等属性均为可空类型,直接调用方法或赋值可能触发空引用异常,建议统一加空值兼容处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 18:54:03