首页 > 解决方案 > 如何使用活动目录请求自动填充 DataGridView

问题描述

我正在尝试从searchResult.FindAll()

我在 Active Directory 中按姓氏进行用户搜索,当多个用户具有相同的姓氏时,我希望数据网格打开并填充具有相同姓氏的所有用户。

我可以检测结果的数量并将信息放入其中,DataGridView但问题是该表每次都填充相同的用户,而不是所有具有相同名称的用户

谢谢你的帮助

foreach (DataGridViewRow row in dataGridView1.Rows)
{
     if (!row.IsNewRow)
     {
            string RNom = row.Cells[1].Value.ToString();

            DirectoryEntry ldapConnection = new DirectoryEntry("LDAP://d21.tes.local", Gid, mdp);
            DirectorySearcher searcher = new DirectorySearcher(ldapConnection);
            searcher.Filter = "(sn=" + RNom + ")";




            foreach (SearchResult result in searcher.FindAll())
            {
                    DirectoryEntry DirEntry = result.GetDirectoryEntry();
                    if (searcher.FindAll().Count > 1)
                    {
                        dataGridView2.RowCount = searcher.FindAll().Count;
                        foreach (DataGridViewRow r in dataGridView2.Rows)
                        {
                            DirectorySearcher ds = new DirectorySearcher();
                            SearchResultCollection resultat = ds.FindAll();
                            foreach (SearchResult sr in resultat)
                            {
                                r.Cells[0].Value = DirEntry.Properties["SAMAccountName"].Value.ToString();
                                r.Cells[1].Value = DirEntry.Properties["sn"].Value.ToString();
                                r.Cells[2].Value = DirEntry.Properties["givenName"].Value.ToString();
                                r.Cells[3].Value = DirEntry.Properties["mail"].Value.ToString();
                            }
                        }
                    }
           }
           else
           {
                    row.Cells[0].Value = DirEntry.Properties["SAMAccountName"].Value.ToString();
                    row.Cells[1].Value = DirEntry.Properties["sn"].Value.ToString();
                    row.Cells[2].Value = DirEntry.Properties["givenName"].Value.ToString();
                    row.Cells[3].Value = DirEntry.Properties["mail"].Value.ToString();
           }
      }
 }

标签: c#datagridviewactive-directory

解决方案


您的代码有几个问题。

这些问题正在影响您的结果:

  1. 该代码不会编译。也许这只是一个复制/粘贴错误,但看起来else应该在里面foreach,而不是外面。
  2. 主要问题是您将结果写在同一行中。您正在循环遍历所有结果,而无需继续下一行。然后在下一行中,您将再次执行所有操作(执行另一次搜索并将所有结果写入同一行)。所以每一行都是一样的,只显示最后一个结果。
  3. dataGridView2您每次都覆盖相同的内容。你应该dataGridView2每次都设置新的东西。
  4. 您正在运行ds.FindAll()没有实际查询字符串的第二次搜索 ( ) - 这些是您正在使用的结果。您想使用第一次搜索的结果 ( searcher.FindAll())

这些问题正在影响您的表现:

  1. 你打searcher.FindAll()了三遍。这将发送到 AD 并执行完全相同的搜索 3 次。
  2. 使用result.GetDirectoryEntry()使其转到 AD 并再次获取属性,而不是使用搜索检索到的数据,这只会减慢您的代码速度而没有任何好处。您可以result.Properties改为使用搜索中返回的数据。
  3. 您可以设置DirectorySearcher.PropertiesToLoad限制返回的属性。如果不设置,将返回所有有值的属性,这是不必要的。你可以通过只询问你需要的东西来加快速度。
  4. 当您使用DirectorySearcher.FindAll时,文档说您需要处理结果,否则最终会导致内存泄漏。

我试图在这里纠正这些问题(除了dataGridView2- 你必须弄清楚):

string RNom = row.Cells[1].Value.ToString();

DirectoryEntry ldapConnection = new DirectoryEntry("LDAP://d21.tes.local", Gid, mdp);
DirectorySearcher searcher = new DirectorySearcher(ldapConnection);
searcher.Filter = "(sn=" + RNom + ")";

searcher.PropertiesToLoad.Add("SAMAccountName");
searcher.PropertiesToLoad.Add("sn");
searcher.PropertiesToLoad.Add("givenName");
searcher.PropertiesToLoad.Add("mail");

using (var results = searcher.FindAll())
{
    if (results.Count > 1)
    {
        var dataGridView2 = ??; //You need to set this to something different each time, otherwise you will just overwrite it
        dataGridView2.RowCount = results.Count;
        var rowId = 0;
        foreach (SearchResult result in results)
        {
            var r = dataGridView2.Rows[rowId];
            r.Cells[0].Value = result.Properties["SAMAccountName"][0];
            r.Cells[1].Value = result.Properties["sn"][0];
            r.Cells[2].Value = result.Properties["givenName"][0];
            r.Cells[3].Value = result.Properties["mail"][0];

            rowId++;
        }
    }
    else if (results.Count == 1)
    {
        var result = results[0];
        row.Cells[0].Value = result.Properties["SAMAccountName"][0];
        row.Cells[1].Value = result.Properties["sn"][0];
        row.Cells[2].Value = result.Properties["givenName"][0];
        row.Cells[3].Value = result.Properties["mail"][0];
    }
    else
    {
        //no results
    }
}

如果您想详细了解如何在与 AD 通信时优化性能,我写了一篇关于该主题的文章:Active Directory:更好的性能


推荐阅读