从using块中返回IQueryable.需要更好的设计

Kin*_*nus 3 c# linq using-statement linq-to-sql

我创建了一个PhoneBook风格的应用程序; 在我的电话簿对象上,我有一个本地成员_site用作过滤器,因为大约有1000个电话号码,分成我组织内的12个站点.使用此方法一次只能检索一个站点.

这是我原来的方法.GUI具有重新排序的数据的方法,所以我把它作为一个IQueryable,因为我想推迟SQL允许过滤要在SQL服务器上,而不是在客户端PC上完成的.

作品

public IQueryable<PhoneNumber> GetPhoneDirectory()
{
    PhoneBookDataContext db = new PhoneBookDataContext())
    return db.PhoneNumbers.Where(d => d.Site == _site);
}
Run Code Online (Sandbox Code Playgroud)

但是,我也在努力保持using声明方面的"最佳实践" .

不起作用

public IQueryable<PhoneNumber> GetPhoneDirectory()
{
    using (PhoneBookDataContext db = new PhoneBookDataContext())
    {
        return db.PhoneNumbers.Where(d => d.Site == _site);
    }
}
Run Code Online (Sandbox Code Playgroud)

正如@justanotheruseryoumay指出的那样,这将导致异常,因为datacontext在访问对象时被释放.

我想我是问,我怎么能保证我的数据上下文是很好的布置,当我不能使用"使用"的语句并在上下文与做不严格知道.

Joe*_*Joe 5

如果您想要返回,IQueryable您可以使您的类包含GetPhoneDirectory一次性,创建PhoneBookDataContext一个字段,并将其处置在您的dispose方法中.

然后,您将把责任放在调用者上以处理他的类的实例.

例如

public class MyClass : IDisposable
{
    PhoneBookDataContext db;

    public MyClass()
    {
        db = new PhoneBookDataContext();
    }

    public IQueryable<PhoneNumber> GetPhoneDirectory()
    {
        return db.PhoneNumbers.Where(d => d.Site == _site);
    }

    public void Dispose()
    {
        if (db != null)
        {
            db.Dispose();
            db = null;
        }
    }
}

// Caller
using(var myClass = new MyClass())
{
    var queryable = myClass.GetPhoneDirectory();
    ...
}
Run Code Online (Sandbox Code Playgroud)