代码之家  ›  专栏  ›  技术社区  ›  VinnyG

norm.mongoexception:尝试从连接池获取连接时的连接超时

  •  0
  • VinnyG  · 技术社区  · 14 年前

    我用的是Rob的MVC StarteSite http://mvcstarter.codeplex.com/ 使用ASP.NET MVC 2、Ninject2、Norm( http://github.com/atheken/NoRM 和MangGDB。它工作得如此之快,开发速度甚至更快,但我面临着一个大问题,我在某些时候,得到了连接超时。我不知道我做错了什么。

    我已经在这里问了一个问题: I get this error that I don't understand why, using NoRM and Mongo in my MVC project 这里 http://groups.google.com/group/norm-mongodb/browse_thread/thread/7882be16f030eb29 但我仍然在黑暗中。

    非常感谢你的帮助!

    编辑* 以下是我的MongoSession对象: 公共类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;
        }
    
    
    }
    
    2 回复  |  直到 13 年前
        1
  •  0
  •   John Zablocki    14 年前

    Vinny

    我从来没有用过ninject,所以我可能会对这个建议感到失望。但是,有一个静态MongoSession实例可能使连接保持打开状态。你有没有尝试过短暂的行为而不是单一的行为?或者在将快捷链接转换为列表后,将代码更改为调用Dispose(或使用)?所有

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

    更好的方法可能是使用某种类型的存储库或DAO,其中会话详细信息对控制器是隐藏的。我有一个仓库样品在 http://www.codevoyeur.com/Articles/20/A-NoRM-MongoDB-Repository-Base-Class.aspx .

    斯图尔特·哈里斯在 http://red-badger.com/Blog/post/A-simple-IRepository3cT3e-implementation-for-MongoDB-and-NoRM.aspx

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

        2
  •  0
  •   VinnyG    14 年前

    如果我在MongoRepositoryBase类的Dispose()方法中添加了throw new NotImplementedException();它不会得到调用,因此我猜Ninject不会为我处理这个问题,如果我有

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

    在我的控制器里,它确实会被调用。看起来很好,谢谢!