2011-04-10 1 views
9

Je viens juste de commencer à jouer avec MongoDB (C#) et j'ai essayé de transférer un dépôt depuis le framework d'entité. J'utilise le pilote C# officiel 1.0. Maintenant, je l'ai fait quelque chose comme ceci:Modèle de référentiel avec MongoDB: Où initialiser la base de données

internal class MongoContext 
{ 
    public MongoContext(string constring) 
    { 
     MongoServer server = MongoServer.Create(constring); 
     this.myDB = server.GetDatabase("MyDB"); 

     BsonClassMap.RegisterClassMap<VoyageNumber>(cm => 
      { cm.MapField<string>(p => p.Id); }); 
     BsonClassMap.RegisterClassMap<Schedule>(cm => 
     { cm.MapField<DateTime>(p => p.EndDate); cm.MapField<DateTime>(p => p.StartDate); }); 
     BsonClassMap.RegisterClassMap<Voyage>(cm => 
      { cm.MapIdField<VoyageNumber>(p => p.VoyageNumber); cm.MapField<Schedule>(p => p.Schedule); }); 

    } 

    private MongoDatabase myDB; 
    public MongoDatabase MyDB 
    { get { return this.myDB; } } 
} 

je puis aller et mettre en œuvre le référentiel comme ceci:

public class MongoVoyageRepository : IVoyageRepository 
{ 
    private readonly MongoContext context; 

    public MongoVoyageRepository(string constring) 
    { 
     this.context = new MongoContext(constring); 
    } 

    public void Store(Domain.Model.Voyages.Voyage voyage) 
    { 

     MongoCollection<Voyage> mongoVoyages = context.MyDB.GetCollection<Voyage>("Voyages"); 

     //store logic... 

    } 

} 

Maintenant, je voudrais savoir si elle est une bonne décision d'instancier un "contexte" comme ça en termes de performance. Est-il sensé de mettre les cartes BsonClass à l'intérieur? Merci de votre contribution.

Répondre

2

Je suppose que cela n'a pas de sens d'enregistrer des mappages de classes chaque fois que vous créez votre classe de référentiel. Puisque le pilote MongoDB C# gère en interne les connexions à MongoDB, il me semble qu'il est préférable de créer MongoServer et d'enregistrer les classes une seule fois, lors du démarrage de l'application, puis de l'utiliser.

J'utilise singleton afin de créer MongoServer une seule fois

public class MongoRead : MongoBase 
{ 
    public MongoRead(MongoServer server) 
      : base(server) 
    { 

    } 


    public override MongoDatabase Database 
    { 
    get { return Server.GetDatabase("myDb"); } 
    } 

    public MongoCollection Logs 
    { 
    get { return Database.GetCollection("logs"); } 
    } 

    private static MongoRead _instance = null; 

    public static MongoRead Instance 
    { 
    get 
     { 
     if (_instance == null) 
     { 
      _instance = RegisterMongoDb(); 

     } 

     return _instance; 
     } 

    } 

    private static MongoRead RegisterMongoDb() 
    { 
     var readServer = MongoServer.Create(connectionString); 
     var read = new MongoRead(readServer); 

     var myConventions = new ConventionProfile(); 
     myConventions.SetIdMemberConvention(new NoDefaultPropertyIdConvention()); 
     BsonClassMap.RegisterConventions(myConventions, t => true); 

     return read; 
    } 

} 

Vous pouvez également utiliser ci-dessus classe dans votre référentiel:

public class MongoVoyageRepository : IVoyageRepository 
{ 
    private readonly MongoRead context 
    { 
     get { return MongoRead.Instance; } 
    }; 

    public MongoVoyageRepository() 
    { 
    } 

    public void Store(Domain.Model.Voyages.Voyage voyage) 
    { 
      MongoCollection<Voyage> mongoVoyages = 
        context.Database.GetCollection<Voyage>("Voyages"); 
      //store logic... 
    } 

} 
+0

Cela fonctionne mais j'ai transformé la propriété Instance en une méthode qui accepte une chaîne de connexion puisque je veux injecter la chaîne de connexion dans le référentiel (IoC). – hoetz

+0

@Malkier: J'utilise aussi IoC adn DI, juste fait 'Instance' car de nombreux développeurs ne connaissent pas IoC, DI ou il semble difficile de se désintéresser;) –

+0

@AndrewOrsich Quelle est la classe' NoDefaultPropertyIdConvention'? –

11
// entity base 
public class MongoEntity { 
    public ObjectId _id { get; set; } 
} 

//user entity 
public class Users : MongoEntity { 
    public string UserName { get; set; } 
    public string Password { get; set; } 
} 


// simple repository 
public class Repository { 

    private MongoDatabase _db; 
    public MongoDatabase Database { get; private set; } 
    public Repository(string constr, string dbname) { 
     var server = MongoServer.Create(constr); 
     _db = server.GetDatabase(dbname); 
     Database = _db; 
    } 

    private MongoCollection<T> GetCollection<T>() where T : MongoEntity { 
     return _db.GetCollection<T>(typeof(T).Name); 
    } 

    public IEnumerable<T> List<T>() where T : MongoEntity { 
     return GetCollection<T>().FindAll(); 
    } 

    public IEnumerable<T> List<T>(Expression<Func<T, bool>> exp) where T : MongoEntity { 
     return GetCollection<T>().AsQueryable<T>().Where(exp); 
    } 

    public T Single<T>(Expression<Func<T, bool>> exp) where T : MongoEntity { 
     return List<T>(exp).SingleOrDefault(); 
    } 

    public void Insert<T>(T entity) where T : MongoEntity { 
     GetCollection<T>().Insert<T>(entity); 
    } 

    public void Insert<T>(ICollection<T> entities) where T : MongoEntity { 
     GetCollection<T>().InsertBatch(entities); 
    } 

    // Update, Delete method etc ... 



} 



// example 
var repository = new Repository("mongodb://localhost", "test"); 
repository.Single<Users>(u => u.UserName == "myUserName"); 
0

this est aussi intéressant si vous voulez utiliser le modèle de référentiel.

Questions connexes