【问题标题】:LINQ to SQL, override disposeLINQ to SQL,覆盖处置
【发布时间】:2012-02-16 14:35:43
【问题描述】:

我通过传递一个已经打开的连接来创建一个 LINQ to SQL DataContext。这行得通,除了我现在到处泄漏连接,因为虽然我在完成后处理了 DataContext,但连接永远不会关闭。我知道这是设计使然。

我想做的是确保我的连接在我的 DataContext 被释放后关闭。

我试图在 DataContext 上覆盖 Dispose,如下所示:

protected override void Dispose(bool disposing)
{
    this.Connection.Close();
}

但是,这不起作用...我得到一个 ObjectDisposedException。设置断点表明此时一切都已处理完毕!

我发现的唯一解决方法是在 DataContext 上隐藏 Dispose 方法。像这样:

    public new void Dispose()
    {
        this.Connection.Close();

        base.Dispose();
    }

但是,这对我来说有点难闻的代码味道。在这里进行的推荐方式是什么?

完整的代码示例(DataClasses1DataContext 是一个空的DataContext):

class Program
{
    static void Main(string[] args)
    {
        string connectionString = "server=localhost;initial catalog=master;Integrated Security=SSPI;";

        for (int i = 0; i < 100; i++)
        {
            var connection = new SqlConnection(connectionString);
            connection.Open();

            var ctx = new DataClasses1DataContext(connection);
            ctx.ExecuteCommand("declare @i int");

            ctx.Dispose();
        }

        Console.ReadKey();
    }
}

public partial class DataClasses1DataContext
{
    protected override void Dispose(bool disposing)
    {
        // This will throw an ObjectDisposedException
        // this.Connection.Close();
    }

    public new void Dispose()
    {
        // This will work
        // this.Connection.Close();

        //base.Dispose();
    }
}

【问题讨论】:

  • override Dispose 方法调用的异常是什么?
  • 我得到一个 ObjectDisposedException
  • ObjectDisposedException 的消息是什么?
  • System.Data.Linq.dll 中发生“System.ObjectDisposedException”类型的未处理异常附加信息:无法访问已处置的对象。
  • 连接对象,实际上是所有上下文的属性,在我隐藏 Dispose(bool disposing) 覆盖时已经被释放。因为首先调用了 Dispose() 方法...

标签: c# linq-to-sql dispose idisposable objectdisposedexception


【解决方案1】:

问题是Dispose() 在调用Dispose(bool) 之前设置了disposed。这会在您调用Connection 时导致异常。似乎没有办法解决这个问题。

但是我不得不问,为什么这是必要的? Dispose(bool) 在包含 ConnectionProvider 上调用 Dispose 并应自动处理关闭它。

【讨论】:

  • 谢谢。从反射器的角度来看,似乎连接仅在某些条件下才被释放(可能,如果它首先是由 Linq to SQL 打开的)。
  • 至少从表面上看,Linq to SQL 似乎没有我可以更改的公共提供程序模型。似乎我的解决方法是唯一的方法。
  • @TheNextman:你在用SqlProvider吗?看来它应该始终关闭连接。除非我错过了 conManager 设置为 null 的某个地方(它是在分支之外构建的)。
  • 阅读Reflector中的代码后我并不清楚。但是,文档(并通过在使用 SQLServer:General Statistics:User Connections 性能计数器时运行我的示例代码进行备份)表明,如果您将 Linq 提供给 SQL 一个已经打开的连接,或者自己打开它的连接对象,它将 不销毁/关闭它
  • 经过进一步调查:如果您使用连接字符串构造 DataContext,L2S 将释放连接。如果您使用连接构建,它不会处理它。有道理:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多