Norm.MongoException:尝试从连接池获取连接时连接超时

发布于 2024-09-13 21:24:21 字数 5315 浏览 1 评论 0 原文

我正在使用 Rob 的 mvc startesite http://mvcstarter.codeplex.com/ 与 ASP.Net MVC 2 、Ninject2、NoRM (http://github.com/atheken/NoRM) 和 MongoDB。它的工作速度如此之快,开发速度甚至更快,但我面临着一个大问题,我在某些时候会出现连接超时。我不明白我做错了什么。

我已经在这里问了一个问题:我在我的 MVC 项目中使用 NoRM 和 Mongo 时遇到此错误,但我不明白为什么 和此处 http://groups.google.com/group/norm-mongodb/browse_thread/thread/7882be16f030eb29 但我仍然一无所知。

非常感谢您的帮助!

已编辑* 这是我的 MongoSession 对象: public class MongoSession : ISession{

    private readonly Mongo _server;

    public MongoSession()
    {
        //this looks for a connection string in your Web.config - you can override this if you want
        _server = Mongo.Create("MongoDB");
    }

    public T Single<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class {
        return _server.GetCollection<T>().AsQueryable().Where(expression).SingleOrDefault();
    }

    public IQueryable<T> All<T>() where T : class {
        return _server.GetCollection<T>().AsQueryable();
    }

    public void Save<T>(IEnumerable<T> items) where T : class {
        foreach (T item in items) {
            Save(item);
        }
    }

    public void Save<T>(T item) where T : class {
        var errors = DataAnnotationsValidationRunner.GetErrors(item);
        if (errors.Count() > 0)
        {
            throw new RulesException(errors);
        }
        _server.Database.GetCollection<T>().Save(item);
    }

    public void Delete<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class
    {
        var items = All<T>().Where(expression);
        foreach (T item in items)
        {
            Delete(item);
        }
    }

    public void Delete<T>(T item) where T : class
    {
        _server.GetCollection<T>().Delete(item);
    }

    public void Drop<T>() where T : class
    {
        _server.Database.DropCollection(typeof(T).Name);

    }

    public void Dispose() {
        _server.Dispose();
    }


}

现在是我的 MongoRepositoryBase

public abstract class MongoRepositoryBase<T> : ISession<T> where T : MongoObject
{
    protected ISession _session;

    protected MongoRepositoryBase(ISession session)
    {
        _session = session;
    }

    public T Single(ObjectId id)
    {
        return _session.All<T>().Where(x => x.Id == id).FirstOrDefault();
    }

    public T Single(Expression<Func<T, bool>> expression)
    {
        return _session.Single(expression);
    }

    public IQueryable<T> All()
    {
        return _session.All<T>();
    }

    public void Save(IEnumerable<T> items)
    {
        foreach (T item in items)
        {
            Save(item);
        }
    }

    public void Save(T item)
    {
        _session.Save(item);
    }

    public void Delete(System.Linq.Expressions.Expression<Func<T, bool>> expression)
    {
        var items = _session.All<T>().Where(expression);
        foreach (T item in items)
        {
            Delete(item);
        }
    }

    public void DeleteAll()
    {
        var items = _session.All<T>();
        foreach (T item in items)
        {
            Delete(item);
        }
    }

    public void Delete(T item)
    {
        _session.Delete(item);
    }

    public void Drop()
    {
        _session.Drop<T>();
    }

    public void Dispose()
    {
        _session.Dispose();
    }
}

以及其他存储库实现的示例:

public class PlaceRepository : MongoRepositoryBase<Place>, IPlaceRepository 
{
    public PlaceRepository(ISession session) : base(session)
    {
    }

    public List<Place> GetByCategory(PlaceCategory category, bool publishedOnly)
    {
        var query = _session.All<Place>()
            .OrderBy(x => x.Name)
            .Where(x => x.Category == category);

        if (publishedOnly) query = query.Where(x => x.Published);
        if (publishedOnly) query = query.Where(x => x.ShowOnMap);

        return query.ToList();
    }

    public Place FindByName(string name)
    {
        var query = _session.All<Place>()
            .Where(x => x.Name.ToLower().Contains(name.ToLower()))
            .Where(x => x.Published);

        return query.FirstOrDefault();
    }

    public string[] FindSuggestionsByName(string name)
    {
        var query = _session.All<Place>()
            .OrderBy(x => x.Name)
            .Where(x => x.Name.ToLower().StartsWith(name.ToLower()))
            .Where(x => x.Published);

        var places = query.ToList();

        var names = new string[places.Count];
        var i = 0;
        foreach (var place in places)
        {
            names[i++] = place.Name;
        }

        return names;
    }


}

I'm using Rob's mvc startesite http://mvcstarter.codeplex.com/ with ASP.Net MVC 2, Ninject2, NoRM (http://github.com/atheken/NoRM) and MongoDB. It works so fast and the developpement is even faster but I'm facing a big problem, I at some points, get connection timeout. I can't figure out what I'm doing wrong.

I already asked a question here : I get this error that I don't understand why, using NoRM and Mongo in my MVC project and here http://groups.google.com/group/norm-mongodb/browse_thread/thread/7882be16f030eb29 but I still in the dark.

Thanks a lot for the help!

EDITED*
Here's my MongoSession object :
public class MongoSession : ISession{

    private readonly Mongo _server;

    public MongoSession()
    {
        //this looks for a connection string in your Web.config - you can override this if you want
        _server = Mongo.Create("MongoDB");
    }

    public T Single<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class {
        return _server.GetCollection<T>().AsQueryable().Where(expression).SingleOrDefault();
    }

    public IQueryable<T> All<T>() where T : class {
        return _server.GetCollection<T>().AsQueryable();
    }

    public void Save<T>(IEnumerable<T> items) where T : class {
        foreach (T item in items) {
            Save(item);
        }
    }

    public void Save<T>(T item) where T : class {
        var errors = DataAnnotationsValidationRunner.GetErrors(item);
        if (errors.Count() > 0)
        {
            throw new RulesException(errors);
        }
        _server.Database.GetCollection<T>().Save(item);
    }

    public void Delete<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class
    {
        var items = All<T>().Where(expression);
        foreach (T item in items)
        {
            Delete(item);
        }
    }

    public void Delete<T>(T item) where T : class
    {
        _server.GetCollection<T>().Delete(item);
    }

    public void Drop<T>() where T : class
    {
        _server.Database.DropCollection(typeof(T).Name);

    }

    public void Dispose() {
        _server.Dispose();
    }


}

And now my MongoRepositoryBase

public abstract class MongoRepositoryBase<T> : ISession<T> where T : MongoObject
{
    protected ISession _session;

    protected MongoRepositoryBase(ISession session)
    {
        _session = session;
    }

    public T Single(ObjectId id)
    {
        return _session.All<T>().Where(x => x.Id == id).FirstOrDefault();
    }

    public T Single(Expression<Func<T, bool>> expression)
    {
        return _session.Single(expression);
    }

    public IQueryable<T> All()
    {
        return _session.All<T>();
    }

    public void Save(IEnumerable<T> items)
    {
        foreach (T item in items)
        {
            Save(item);
        }
    }

    public void Save(T item)
    {
        _session.Save(item);
    }

    public void Delete(System.Linq.Expressions.Expression<Func<T, bool>> expression)
    {
        var items = _session.All<T>().Where(expression);
        foreach (T item in items)
        {
            Delete(item);
        }
    }

    public void DeleteAll()
    {
        var items = _session.All<T>();
        foreach (T item in items)
        {
            Delete(item);
        }
    }

    public void Delete(T item)
    {
        _session.Delete(item);
    }

    public void Drop()
    {
        _session.Drop<T>();
    }

    public void Dispose()
    {
        _session.Dispose();
    }
}

And an exemple of an other Repository implemantation :

public class PlaceRepository : MongoRepositoryBase<Place>, IPlaceRepository 
{
    public PlaceRepository(ISession session) : base(session)
    {
    }

    public List<Place> GetByCategory(PlaceCategory category, bool publishedOnly)
    {
        var query = _session.All<Place>()
            .OrderBy(x => x.Name)
            .Where(x => x.Category == category);

        if (publishedOnly) query = query.Where(x => x.Published);
        if (publishedOnly) query = query.Where(x => x.ShowOnMap);

        return query.ToList();
    }

    public Place FindByName(string name)
    {
        var query = _session.All<Place>()
            .Where(x => x.Name.ToLower().Contains(name.ToLower()))
            .Where(x => x.Published);

        return query.FirstOrDefault();
    }

    public string[] FindSuggestionsByName(string name)
    {
        var query = _session.All<Place>()
            .OrderBy(x => x.Name)
            .Where(x => x.Name.ToLower().StartsWith(name.ToLower()))
            .Where(x => x.Published);

        var places = query.ToList();

        var names = new string[places.Count];
        var i = 0;
        foreach (var place in places)
        {
            names[i++] = place.Name;
        }

        return names;
    }


}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

呆橘 2024-09-20 21:24:21

Vinny,

我从未使用过 Ninject,所以我可能会远离这个建议。但静态 MongoSession 实例似乎可能会保持连接打开。您是否尝试过 TransientBehavior 而不是 SingletonBehavior?或者,在将 ShortcutLinks 转换为列表后,可以更改代码以调用 Dispose (或使用 using)? 更好的方法可能

var shortcutLionks = _session.All<ShortcutLinks>().ToList();
_session.Dispose();

是使用某种存储库或 DAO,其中会话详细信息对控制器隐藏。我在 http:// 有一个 RepositoryBase 示例www.codevoyeur.com/Articles/20/A-NoRM-MongoDB-Repository-Base-Class.aspx

Stuart Harris 在 http://red-badger.com/Blog/post/A-simple-IRepository3cT3e-implementation-for-MongoDB-and-NoRM.aspx

池化 MongoDB 连接的创建成本相对较低,因此最好确保在完成获取/保存数据后处理数据访问方法。

Vinny,

I've never used Ninject, so I could be way off with this suggestion. But it seems possible that having a static MongoSession instance might be holding connections open. Have you tried TransientBehavior instead of SingletonBehavior? Or maybe change your code to call Dispose (or use using) after you convert your ShortcutLinks to a List? All

var shortcutLionks = _session.All<ShortcutLinks>().ToList();
_session.Dispose();

A better approach might be to use some sort of repository or DAO where the session details are hidden from the controller. I have a RepositoryBase sample at http://www.codevoyeur.com/Articles/20/A-NoRM-MongoDB-Repository-Base-Class.aspx.

Stuart Harris has a similar, arguably more complete implementation at http://red-badger.com/Blog/post/A-simple-IRepository3cT3e-implementation-for-MongoDB-and-NoRM.aspx

Pooled MongoDB connections are relatively cheap to create, so it's probably best to make sure the data access methods are disposing after your done getting/saving data.

给不了的爱 2024-09-20 21:24:21

如果我添加 throw new NotImplementedException();在我的 MongoRepositoryBase 类的 Dispose() 方法中,它不会被调用,所以我猜 Ninject 不会为我处理这个问题,如果我

protected override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            _recipeRepo.Dispose();
            base.OnActionExecuted(filterContext);
        }

在我的控制器中它确实会被调用。看起来好像还好,thx!

If I add throw new NotImplementedException(); in the Dispose() method of my MongoRepositoryBase class it does not get call so I guess Ninject does not handle this for me, If I had

protected override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            _recipeRepo.Dispose();
            base.OnActionExecuted(filterContext);
        }

In my controller it does get call. It seems to be fine, thx!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文