Norm.MongoException: Тайм-аут соединения, пытающийся получить соединение от пула соединений - PullRequest
0 голосов
/ 10 августа 2010

Я использую mvc startesite Роба http://mvcstarter.codeplex.com/ с ASP.Net MVC 2, Ninject2, NoRM (http://github.com/atheken/NoRM) и MongoDB. Это работает так быстро, и разработка происходит еще быстрее, но я столкнувшись с большой проблемой, я в некоторых моментах получаю тайм-аут соединения. Я не могу понять, что я делаю неправильно.

Я уже задавал вопрос здесь: Я получаю эту ошибку, которую я не понимаю, почему, используя NoRM и Mongo в моем проекте MVC и здесь http://groups.google.com/group/norm-mongodb/browse_thread/thread/7882be16f030eb29, но я все еще в неведении .

Большое спасибо за помощь!

EDITED * Вот мой объект 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 ]

0 голосов
/ 11 августа 2010

Если я добавлю бросить новый NotImplementedException ();в методе Dispose () моего класса MongoRepositoryBase он не получает вызов, поэтому я предполагаю, что Ninject не обрабатывает это для меня, если у меня было

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

В моем контроллере он получает вызов.Кажется, все в порядке, спасибо!

0 голосов
/ 10 августа 2010

Винни,

Я никогда не использовал Ninject, так что я могу быть далеко от этого предложения.Но кажется возможным, что наличие статического экземпляра MongoSession может держать соединения открытыми.Вы пробовали TransientBehavior вместо SingletonBehavior?Или, может быть, изменить свой код для вызова Dispose (или использовать с помощью) после преобразования ваших ShortcutLinks в список?Все

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

Лучшим подходом может быть использование какого-либо хранилища или DAO, где детали сеанса скрыты от контроллера.У меня есть образец RepositoryBase на http://www.codevoyeur.com/Articles/20/A-NoRM-MongoDB-Repository-Base-Class.aspx.

У Стюарта Харриса есть похожая, возможно, более полная реализация на http://red -badger.com / Blog / post / A-simple-IRepository3cT3e-реализация для MongoDB-and-NoRM.aspx

Соединения в пул с MongoDB относительно дешевы в создании, поэтому, вероятно, лучше всего убедиться, что методы доступа к данным удаляются после того, как вы получили / сохранили данные.

...