Sé que se supone que MongoDB no es compatible con la unidad de trabajo, etc. Pero creo que sería bueno implementar el repositorio que almacenaría solo las intenciones (similar a los criterios) y luego ellos a la DB. De lo contrario, en cada método en su repositorio debe crear una conexión a DB y luego cerrarlo. Si colocamos la conexión a DB en alguna clase de BaseRepository, vinculamos nuestro repositorio a DB concreto y es realmente difícil probar repositorios, probar IoC que resuelven repositorios.Unidad de trabajo en mongodb y C#
¿Está creando una sesión en MongoDB una mala idea? ¿Hay alguna manera de separar la lógica de conexión del repositorio?
Aquí hay un código de Rob Conery. ¿Es una buena idea conectarse siempre a su base de datos en cada solicitud? cual es la mejor practica?
Hay una cosa más. Imagina que quiero proporcionar un índice para una colección. Anteriormente lo hice en un constructor pero con el enfoque de Rob esto parece fuera de lógica hacerlo allí.
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();
}
}
¿Qué tal la inyección de dependencia a través de un marco (o auto-escrito)? – DrColossos
@DrColossos, en realidad uso un framework llamado Castle.Windsor. He visto un código de Rob Conery simulando sesiones, pero se conecta a DB en cada creación/actualización/eliminación/búsqueda y no, si es óptimo –