首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Sonic未关闭连接

Sonic未关闭连接
EN

Stack Overflow用户
提问于 2009-11-13 03:28:55
回答 2查看 703关注 0票数 0

我正在使用SubSonic 3中的Linq,如下所示:

代码语言:javascript
复制
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没有关闭connections...so,我用完了池中的SQL连接,或者MySQL只是拒绝允许更多的连接……我已经在SS 3.0.3和SVN上尝试过了,我一直收到这些错误。

在我得到一组结果后,我应该做什么来关闭连接?

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-11-13 12:20:28

信不信由你,问题不在SubSonic。这是$*$&$ MySQL驱动程序。当你执行这样的查询时,我们会显式地关闭连接,但我看到MySQL驱动程序完全忽略了关闭,转而支持一些非常非常差劲的优化尝试。

我不知道该在这里跟你说什么--我很抱歉地说。

票数 3
EN

Stack Overflow用户

发布于 2009-12-31 13:57:38

MySQL .NET库似乎有一些问题。几天前,他们在6.2.2版本中修复了一些与释放连接相关的问题。但是SubSonic也有一个问题。我使用带有MySQL的LINQ模板来生成我的类。每当FirstOrDefault()或First() (其他类似的函数可能也有同样的问题)。

对于查询,例如:

代码语言:javascript
复制
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();

这将导致查询被执行,并且读取器将不会被释放()。

问题出在T方法项目的Linq.Structure.DbQueryProvider中。

代码语言:javascript
复制
while (reader.Read())
{
    yield return fnProjector(reader);
}
reader.Dispose();

在使用FirstOrDefault()和其他类似方法时,Dispose()从不会被调用。

一个简单的解决方法:

代码语言:javascript
复制
try
{
    while (reader.Read())
    {
        yield return fnProjector(reader);
    }
}
finally
{
    reader.Dispose();
}

显示问题的简单快速测试:

代码语言:javascript
复制
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上分叉了这个项目,提交了我的更改,并做了一个拉取请求,希望能得到正确的人。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1724760

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档