从using语句包装的另一个类中检索数据的正确方法

本文关键字:数据 检索 方法 using 语句 包装 另一个 | 更新日期: 2023-09-27 17:53:16

我得到一个异常

不能访问已处置的对象。

我知道我得到了这个异常,因为对象在有机会返回结果之前已经被处理了。我想知道的是什么是正确的方法来检索对象。我可能有不必要的步骤在我的代码和可能做这一切都错了?

我有一个按钮点击事件在我的主类。它调用下面代码中所示的方法。GetADComputer方法位于另一个名为ActiveDirectory.cs的类中。当试图访问已处置对象的结果时,我遇到了异常。

public static PrincipalSearchResult<Principal> GetADComputer(string pcName)
{
    using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
    {
        using (ComputerPrincipal computer = new ComputerPrincipal(ctx))
        {
            computer.Name = String.Format("*{0}*", pcName);
            using (PrincipalSearcher searcher = new PrincipalSearcher())
            {
                searcher.QueryFilter = computer;
                return searcher.FindAll();
            }
        }
    }            
}    

从using语句包装的另一个类中检索数据的正确方法

问题是DirectoryServices使用延迟加载它的信息,所以因为你关闭了上下文,你不能从Principal检索信息了。

您有两个选项,要么将PrincipalContext传递到查询中,这样当您返回时它就不会超出范围:

public static DoSomthing()
{
    using(var ctx = new PrincipalContext(ContextType.Domain))
    using(PrincipalSearchResult<Principal> result = GetADComputer("some Name", ctx))
    {
        //do something with the result here.
    }
}
public static PrincipalSearchResult<Principal> GetADComputer(string pcName, PrincipalContext ctx)
{
    using (var computer = new ComputerPrincipal(ctx))
    {
        computer.Name = String.Format("*{0}*", pcName);
        using (var searcher = new PrincipalSearcher())
        {
            searcher.QueryFilter = computer;
            return searcher.FindAll();
        }
    }
} 

或者您需要将结果转换为不依赖于延迟加载的内容,以便您可以关闭与目录服务器的连接。

public static List<ComputerInfo> GetADComputer(string pcName, PrincipalContext ctx)
{
    using (var computer = new ComputerPrincipal(ctx))
    {
        computer.Name = String.Format("*{0}*", pcName);
        using (var searcher = new PrincipalSearcher())
        {
            searcher.QueryFilter = computer;
            using (PrincipalSearchResult<Principal> result = searcher.FindAll())
            {
                return result.Select(p=> new ComputerInfo(p.Name, p.SID)).ToList();
            }
        }
    }
} 
public class ComputerInfo
{
    public ComputerInfo(string name, SecurityIdentifier sid)
    {
        Name = name;
        SID = sid;
    }
    public string Name {get; set;}
    public SecurityIdentifier SID {get; set;}
}