我正在使用SubSonic 3中的Linq:
for(int x; x < 100; x++) {
var v = (from c in db.categories
where c.parent == 10
select c);
if (v.Count() > 0) return null;
category[] c = v.ToArray();
}
由于某种原因,SubSonic没有关闭连接...所以在上面的循环运行几次之后我在池中没有SQL连接或MySQL只是拒绝允许更多的连接......我试过这两个使用SS 3.0.3和SVN,我不断收到这些错误。
在得到一组结果后,我应该怎么做才能关闭连接?
由于
答案 0 :(得分:3)
问题 - 信不信由你 - 不是SubSonic。这是$ * $&amp; $ MySQL驱动程序。当你进行这样的查询时,我们明确地关闭了连接,但是我已经看到MySQL驱动程序完全忽略了关闭,而忽略了一些非常非常蹩脚的优化尝试。
我不知道该告诉你什么 - 我很遗憾地说。
答案 1 :(得分:3)
MySQL .NET库似乎存在一些问题。几天前,他们修复了与发布连接有关的6.2.2中的一些问题。 但SubSonic也存在问题。我使用MySQL的LINQ模板来生成我的类。每当FirstOrDefault()或First()(其他类似函数可能有相同的问题)时。
对于诸如以下的查询:
var db = new MyDb("CONNECTIONSTRING_NAME");
var userExt = (from pe in db.PhoneExtensions
where
pe.FirstName.ToLower() == firstName.ToLower() &&
pe.LastName.ToLower() == lastName.ToLower()
select pe.Extension).FirstOrDefault();
这将导致查询被执行,读者将不被处理。
问题出在Project of T方法的Linq.Structure.DbQueryProvider中。
while (reader.Read())
{
yield return fnProjector(reader);
}
reader.Dispose();
使用FirstOrDefault()和其他类似方法时,Dispose()永远不会被调用。
简单修复:
try
{
while (reader.Read())
{
yield return fnProjector(reader);
}
}
finally
{
reader.Dispose();
}
简单快速测试显示问题:
private class DbDataReader : System.IDisposable
{
#region IDisposable Members
public void Dispose() { }
#endregion
}
private class DbQueryProvider
{
private DbDataReader _reader;
public bool IsReaderDisposed { get { return _reader == null; } }
public DbQueryProvider()
{
_reader = new DbDataReader();
}
public IEnumerable<int> Project(int numResults)
{
int i = 0;
while (i < numResults)
{
yield return i++;
}
_reader.Dispose();
_reader = null;
}
public IEnumerable<int> ProjectWithFinally(int numResults)
{
int i = 0;
try
{
while (i < numResults)
{
yield return i++;
}
}
finally
{
_reader.Dispose();
_reader = null;
}
}
}
[Test]
public void YieldReturn_Returns_TrueForIsReaderDisposed()
{
const int numResults = 1;
var qp1 = new DbQueryProvider();
var q1 = qp1.Project(numResults);
Assert.IsInstanceOf(typeof(int), q1.First());
var qp2 = new DbQueryProvider();
var q2 = qp2.Project(numResults);
Assert.IsInstanceOf(typeof(int), q2.FirstOrDefault());
var qp3 = new DbQueryProvider();
var q3 = qp3.Project(numResults);
Assert.IsInstanceOf(typeof(int), q3.Single());
var qp4 = new DbQueryProvider();
var q4 = qp4.Project(numResults);
Assert.IsInstanceOf(typeof(int), q4.SingleOrDefault());
Assert.IsTrue(qp1.IsReaderDisposed);
Assert.IsTrue(qp2.IsReaderDisposed);
Assert.IsTrue(qp3.IsReaderDisposed);
Assert.IsTrue(qp4.IsReaderDisposed);
}
[Test]
public void YieldReturnFinally_Returns_TrueForIsReaderDisposed()
{
const int numResults = 1;
var qp1 = new DbQueryProvider();
var q1 = qp1.ProjectWithFinally(numResults);
Assert.IsInstanceOf(typeof(int), q1.First());
var qp2 = new DbQueryProvider();
var q2 = qp2.ProjectWithFinally(numResults);
Assert.IsInstanceOf(typeof(int), q2.FirstOrDefault());
var qp3 = new DbQueryProvider();
var q3 = qp3.ProjectWithFinally(numResults);
Assert.IsInstanceOf(typeof(int), q3.Single());
var qp4 = new DbQueryProvider();
var q4 = qp4.ProjectWithFinally(numResults);
Assert.IsInstanceOf(typeof(int), q4.SingleOrDefault());
Assert.IsTrue(qp1.IsReaderDisposed);
Assert.IsTrue(qp2.IsReaderDisposed);
Assert.IsTrue(qp3.IsReaderDisposed);
Assert.IsTrue(qp4.IsReaderDisposed);
}
YieldReturnFinally_Returns_TrueForIsReaderDisposed传递,但YieldReturn_Returns_TrueForIsReaderDisposed失败。
我已经在我正在开发的项目上对此进行了测试,该项目即将投入生产,这似乎没有任何问题。测试连接池最大大小为5并且没有连接池问题(在一次执行1个查询时,我的开发机器上的连接从未耗尽)。 我还在Extensions.Database中发现了与类型更改和分配相关的一些问题。
我在github上分叉了这个项目,提交了我的更改并做了拉取请求,希望能找到合适的人。