LINQ to SQL, override dispose
-
26-10-2019 - |
سؤال
I am creating a LINQ to SQL DataContext by passing it an already open connection. This works, except I'm now leaking connections everywhere because although I dispose the DataContext when I'm finished, the connection never gets closed. I understand this is by design.
What I would like to do is ensure that my connection gets closed once my DataContext is disposed.
I have tried to override Dispose on the DataContext, like this:
protected override void Dispose(bool disposing)
{
this.Connection.Close();
}
However, this does not work... I get an ObjectDisposedException. Setting a breakpoint shows me that everything is already disposed at this point!
The only workaround I have found, is to hide the Dispose method on DataContext. Like this:
public new void Dispose()
{
this.Connection.Close();
base.Dispose();
}
However, this has a bit of a bad code smell to me. What is the recommended way to proceed here?
Complete code sample (DataClasses1DataContext is an empty 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();
}
}
المحلول
The problem is Dispose()
sets disposed
before calling Dispose(bool)
. This causes the exception when you call Connection
. There does not appear to be a way around this.
However I have to ask, why is this necessary? Dispose(bool)
calls Dispose
on the Provider
which contains the Connection
and should handle closing it automatically.