So che MongoDB non suppone supportare unità di lavoro, ecc. Ma penso che sarebbe bello implementare il repository che memorizzerebbe solo le intenzioni (simili ai criteri) e quindi eseguirà il commit loro al DB. Altrimenti in ogni metodo nel tuo repository devi creare una connessione a DB e quindi chiuderla. Se poniamo la connessione al DB in una classe BaseRepository, leghiamo il nostro repository al DB concreto ed è molto difficile testare gli archivi, per testare IoC che risolve i repository.Unità di lavoro in mongodb e C#
Creare una sessione in MongoDB è una cattiva idea? C'è un modo per separare la logica di connessione dal repository?
Ecco un codice di Rob Conery. È una buona idea connettersi sempre al tuo DB ad ogni richiesta? Qual è la migliore pratica?
C'è ancora una cosa. Immagina di voler fornire un indice per una collezione. In precedenza ho lavorato in un costruttore, ma con l'approccio di Rob non sembra logico farlo lì.
using Norm;
using Norm.Responses;
using Norm.Collections;
using Norm.Linq;
public class MongoSession {
private string _connectionString;
public MongoSession() {
//set this connection as you need. This is left here as an example, but you could, if you wanted,
_connectionString = "mongodb://127.0.0.1/MyDatabase?strict=false";
}
public void Delete<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class, new() {
//not efficient, NoRM should do this in a way that sends a single command to MongoDB.
var items = All<T>().Where(expression);
foreach (T item in items) {
Delete(item);
}
}
public void Delete<T>(T item) where T : class, new() {
using(var db = Mongo.Create(_connectionString))
{
db.Database.GetCollection<T>().Delete(item);
}
}
public void DeleteAll<T>() where T : class, new() {
using(var db = Mongo.Create(_connectionString))
{
db.Database.DropCollection(typeof(T).Name);
}
}
public T Single<T>(System.Linq.Expressions.Expression<Func<T, bool>> expression) where T : class, new() {
T retval = default(T);
using(var db = Mongo.Create(_connectionString))
{
retval = db.GetCollection<T>().AsQueryable()
.Where(expression).SingleOrDefault();
}
return retval;
}
public IQueryable<T> All<T>() where T : class, new() {
//don't keep this longer than you need it.
var db = Mongo.Create(_connectionString);
return db.GetCollection<T>().AsQueryable();
}
public void Add<T>(T item) where T : class, new() {
using(var db = Mongo.Create(_connectionString))
{
db.GetCollection<T>().Insert(item);
}
}
public void Add<T>(IEnumerable<T> items) where T : class, new() {
//this is WAY faster than doing single inserts.
using(var db = Mongo.Create(_connectionString))
{
db.GetCollection<T>().Insert(items);
}
}
public void Update<T>(T item) where T : class, new() {
using(var db = Mongo.Create(_connectionString))
{
db.GetCollection<T>().UpdateOne(item, item);
}
}
//this is just some sugar if you need it.
public T MapReduce<T>(string map, string reduce) {
T result = default(T);
using(var db = Mongo.Create(_connectionString))
{
var mr = db.Database.CreateMapReduce();
MapReduceResponse response =
mr.Execute(new MapReduceOptions(typeof(T).Name) {
Map = map,
Reduce = reduce
});
MongoCollection<MapReduceResult<T>> coll = response.GetCollection<MapReduceResult<T>>();
MapReduceResult<T> r = coll.Find().FirstOrDefault();
result = r.Value;
}
return result;
}
public void Dispose() {
_server.Dispose();
}
}
E riguardo l'iniezione di dipendenza tramite un framework (o auto-scritto)? – DrColossos
@DrColossos, in realtà utilizzo un framework chiamato Castle.Windsor. Ho visto un codice di Rob Conery che simula le sessioni ma si connette a DB su ogni creazione/aggiornamento/cancellazione/ricerca e io no se è ottimale –