Active Directory查询结果填充DataGridView重复数据问题求助
解决你的AD用户搜索重复填充问题
让我仔细看看你的代码——问题核心是循环逻辑混乱,加上重复调用AD查询、错误复用对象,导致所有行都被填充成同一个用户。咱们一步步拆解问题并修正:
你的代码里的几个关键问题
- 重复创建资源且多次查询AD:每次遍历
dataGridView1的行都新建LDAP连接,还多次调用searcher.FindAll(),这不仅浪费资源,还容易因为AD查询的延迟或重复获取导致逻辑错误。 - 结果处理逻辑完全错误:当检测到多个结果时,你重新创建了一个没有设置过滤条件的
DirectorySearcher,这会返回整个AD的用户列表;而且内层循环一直用最开始的那个DirEntry填充所有行,自然所有行都是同一个用户。 - 行填充方式反了:你先设置
RowCount再循环填充,不如直接逐个添加新行更直观,也不容易搞混索引。
修正后的代码
我重构了你的代码,解决了上述问题,还加了一些容错处理:
// 把LDAP连接放到外层,避免重复创建,提升效率同时减少AD服务器压力 using (DirectoryEntry ldapConnection = new DirectoryEntry("LDAP://d21.tes.local", Gid, mdp)) { foreach (DataGridViewRow row in dataGridView1.Rows) { // 跳过新行,同时判断单元格值不为空,避免空引用异常 if (!row.IsNewRow && row.Cells[1].Value != null) { string targetLastName = row.Cells[1].Value.ToString().Trim(); DirectorySearcher searcher = new DirectorySearcher(ldapConnection); // 设置过滤条件,注意如果姓氏有特殊字符可能需要转义,这里先按你的逻辑来 searcher.Filter = $"sn={targetLastName}"; // 只调用一次FindAll(),把结果存起来,避免多次查询AD using (SearchResultCollection searchResults = searcher.FindAll()) { // 先清空DataGridView2的旧数据,避免残留之前的搜索结果 dataGridView2.Rows.Clear(); if (searchResults.Count > 0) { foreach (SearchResult result in searchResults) { // 使用using包裹DirectoryEntry,确保资源被正确释放 using (DirectoryEntry userEntry = result.GetDirectoryEntry()) { // 逐个获取属性,加null判断防止用户缺少某个属性时崩溃 string samAccount = userEntry.Properties["SAMAccountName"].Value?.ToString() ?? ""; string lastName = userEntry.Properties["sn"].Value?.ToString() ?? ""; string firstName = userEntry.Properties["givenName"].Value?.ToString() ?? ""; string email = userEntry.Properties["mail"].Value?.ToString() ?? ""; // 直接添加新行并填充数据,不用提前设置RowCount int newRowIdx = dataGridView2.Rows.Add(); dataGridView2.Rows[newRowIdx].Cells[0].Value = samAccount; dataGridView2.Rows[newRowIdx].Cells[1].Value = lastName; dataGridView2.Rows[newRowIdx].Cells[2].Value = firstName; dataGridView2.Rows[newRowIdx].Cells[3].Value = email; } } } else { // 如果没有找到匹配用户,可以添加提示行或者留空 dataGridView2.Rows.Add("未找到匹配的用户", "", "", ""); } } } } }
额外的优化建议
- 过滤条件转义:如果用户的姓氏包含AD过滤的特殊字符(比如
*、(、)等),需要先转义,否则会导致查询出错。可以写个简单的转义方法处理这些字符。 - 性能优化:如果
dataGridView1里有很多行,考虑异步查询AD,避免UI卡顿。 - 属性预加载:可以给
searcher.PropertiesToLoad添加需要的属性名,比如searcher.PropertiesToLoad.AddRange(new string[] {"SAMAccountName", "sn", "givenName", "mail"});,这样AD只会返回你需要的属性,提升查询速度。
内容的提问来源于stack exchange,提问作者Statiikz
相关产品推荐
相关产品推荐

