2010-08-10 30 views
0

J'utilise le démarrage de mvc de Rob http://mvcstarter.codeplex.com/ avec ASP.Net MVC 2, Ninject2, NoRM (http://github.com/atheken/NoRM) et MongoDB. Cela fonctionne tellement vite et le développement est encore plus rapide mais je suis confronté à un gros problème, je suis à certains moments, obtenir un délai de connexion. Je ne peux pas comprendre ce que je fais mal.Norm.MongoException: Délai de connexion essayant d'obtenir la connexion du pool de connexion

J'ai déjà posé une question ici: I get this error that I don't understand why, using NoRM and Mongo in my MVC project et ici http://groups.google.com/group/norm-mongodb/browse_thread/thread/7882be16f030eb29 mais je suis toujours dans le noir.

Merci beaucoup pour votre aide!

RÉVISÉ * Voici mon objet 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(); 
    } 


} 

Et maintenant mon 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(); 
    } 
} 

Et un exemple d'un autre dépôt 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; 
    } 


} 
+0

bien que c'était facile - doublon possible de [Je reçois cette erreur que je ne comprends pas pourquoi, en utilisant NoRM et Mongo dans mon projet MVC] (http://stackoverflow.com/questions/3159811/i-get- cette-erreur-que-je-ne-comprends-pas-utilise-norme-et-mongo-dans-mon-mvc-proj) – jfar

+0

Je sais, cela me rend fou! Je l'ai pensé avec un autre titre et une explication différente et un mot-clé peut-être que je pourrais trouver quelqu'un pour m'aider ... J'ai ajouté plus de code. – VinnyG

Répondre

0

Vinny,

Je n'ai jamais utilisé Ninject, donc je pourrais être loin de cette suggestion. Mais il semble possible qu'avoir une instance statique de MongoSession puisse maintenir des connexions ouvertes. Avez-vous essayé TransientBehavior au lieu de SingletonBehavior? Ou peut-être changer votre code pour appeler Dispose (ou utiliser using) après avoir converti vos ShortcutLinks à une liste? Tous les

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

Une meilleure approche pourrait être d'utiliser une sorte de référentiel ou DAO où les détails de session sont cachés du contrôleur. J'ai un exemple RepositoryBase à http://www.codevoyeur.com/Articles/20/A-NoRM-MongoDB-Repository-Base-Class.aspx.

Stuart Harris a une application similaire, sans doute plus complet à http://red-badger.com/Blog/post/A-simple-IRepository3cT3e-implementation-for-MongoDB-and-NoRM.aspx

connexions Pooled MongoDB sont relativement pas cher pour créer, il est donc probablement préférable de vous assurer que les méthodes d'accès aux données sont débarrassent après votre fait obtenir/la sauvegarde des données.

+0

Thx John pour la réponse, j'ai essayé TrahsientBehavior et j'ai toujours le même problème. Je suis plutôt sur parce que je ne ferme pas ou ne dispose pas de ma connexion mais j'ai pensé que Ninject ferait cela pour moi. J'ai une classe de dépôt de base qui ressemble beaucoup à vos posts, tout en cherchant la meilleure façon de gérer ma session de mongo que j'ai trouvée, je vais l'essayer ce soir ou demain matin pour voir si j'ai toujours le même problème . – VinnyG

0

Si j'ajoute throw new NotImplementedException(); dans la méthode de ma classe MongoRepositoryBase Dispose() ne je suppose que s'appeler pas si Ninject ne gère pas ça pour moi, si j'avais

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

Dans mon contrôleur, il ne s'appeler. Ça a l'air d'aller bien, merci!