为什么primaryalsearcher代码明显变慢

时间:2014-10-22 01:30:22

标签: c# asp.net-web-api directoryservices

我有一个为用户分配用户名的Web服务。在内部我调用了一堆函数来验证AD中是否存在用户名,包括UserPrincipal,samAccountName,proxyaddresses和email。

在单元测试中,此代码需要10秒才能运行。在本地部署到Web服务器,代码运行需要9分钟。我不认为这是第一次运行的问题,因为它第二次需要很长时间。我们的域名拥有超过30,000的用户,我必须搜索整个域名,以确保名称不存在。根据要求,不能使用缓存,因为我们需要进行最新的检查。

我已经搜索了如何提高速度,但还没有找到任何东西。

任何人都有关于如何提高绩效的建议吗?

    public bool DoesEmailExist(string email)
    {
        using (var context = GetPrincipalContext())
        {
            var userQuery = new UserPrincipal(context) { EmailAddress = email + "@*" };

            var searcher = new PrincipalSearcher(userQuery);

            var result = searcher.FindOne();

            if (result == null)
            {
                var aliasQuery = new ExtendedUserPrincipal(context) { ProxyAddress = "*smtp:" + email + "@*" };

                searcher = new PrincipalSearcher(aliasQuery);

                var aliasResult = searcher.FindOne();

                if (result == null)
                {
                    return false;
                }
            }

            return true;
        }
    }

    private PrincipalContext GetPrincipalContext(string ou)
    {
            return new PrincipalContext(ContextType.Domain, dc, ou, ContextOptions.Negotiate);
    }

编辑 - 我切换到使用DirectorySearcher,速度似乎有所改善。现在运行的网络API需要5分钟。我仍然想知道为什么我的单元测试明显快于web api。使用日志代码,单元测试中对DoesUserNameExist的调用需要7秒。通过运行web api需要5分钟。

    public bool DoesUserNameExist(string userName)
    {
        string filter = "(|(samAccountName={NAME})(UserPrincipalName={NAME}@*)(mail={NAME}@*)(proxyAddresses=*smtp:{NAME}@*))";

        filter = filter.Replace("{NAME}", userName);

        using (var de = new DirectoryEntry("LDAP://" + domainController + "/" + rootOU))
        {
            var searcher = new DirectorySearcher();
            searcher.Filter = filter;
            searcher.PageSize = 1;
            var result = searcher.FindOne();

            if (result != null)
            {
                return true;
            }

            return false;
        }
    }

1 个答案:

答案 0 :(得分:2)

尽管proxyAddresses属性已编制​​索引,但它仅对等号和启动过滤器有帮助,但不包含end-with和包含过滤器。

  • 快速:proxyAddresses=sthproxyAddresses=sth*
  • 慢:proxyAddresses=*sth*proxyAddresses=*sth

我认为没有看起来像“abcdsmtp:user@domain.com”的proxyAddresses。
您只需使用proxyAddresses=smtp:{NAME}@*

即可