mongodb和C#的工作单位

我知道MongoDB不应该支持工作单元等。但我认为实现只存储意图(类似于标准)然后将它们提交给DB的存储库会很好。 否则,在存储库中的每个方法中,您都必须创建与DB的连接,然后将其关闭。 如果我们将连接放在某个BaseRepository类中的DB,那么我们将我们的存储库绑定到具体的数据库,并且测试存储库非常困难,以测试解决存储库的IoC。

在MongoDB中创建会话是个坏主意吗? 有没有办法将连接逻辑与存储库分开?

以下是Rob Conery的一些代码。 在每次请求时始终连接到您的数据库是一个好主意吗? 什么是最佳做法?

还有一件事。 想象一下,我想为集合提供索引。 以前我在构造函数中做过,但是使用Rob的方法,这似乎不符合逻辑。

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(System.Linq.Expressions.Expression<Func> expression) where T : class, new() { //not efficient, NoRM should do this in a way that sends a single command to MongoDB. var items = All().Where(expression); foreach (T item in items) { Delete(item); } } public void Delete(T item) where T : class, new() { using(var db = Mongo.Create(_connectionString)) { db.Database.GetCollection().Delete(item); } } public void DeleteAll() where T : class, new() { using(var db = Mongo.Create(_connectionString)) { db.Database.DropCollection(typeof(T).Name); } } public T Single(System.Linq.Expressions.Expression<Func> expression) where T : class, new() { T retval = default(T); using(var db = Mongo.Create(_connectionString)) { retval = db.GetCollection().AsQueryable() .Where(expression).SingleOrDefault(); } return retval; } public IQueryable All() where T : class, new() { //don't keep this longer than you need it. var db = Mongo.Create(_connectionString); return db.GetCollection().AsQueryable(); } public void Add(T item) where T : class, new() { using(var db = Mongo.Create(_connectionString)) { db.GetCollection().Insert(item); } } public void Add(IEnumerable items) where T : class, new() { //this is WAY faster than doing single inserts. using(var db = Mongo.Create(_connectionString)) { db.GetCollection().Insert(items); } } public void Update(T item) where T : class, new() { using(var db = Mongo.Create(_connectionString)) { db.GetCollection().UpdateOne(item, item); } } //this is just some sugar if you need it. public T MapReduce(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> coll = response.GetCollection<MapReduceResult>(); MapReduceResult r = coll.Find().FirstOrDefault(); result = r.Value; } return result; } public void Dispose() { _server.Dispose(); } } 

不要过于担心打开和关闭连接。 MongoDB C#驱动程序维护一个内部连接池,因此每次创建新的MongoServer对象时都不会产生打开和关闭实际连接的开销。

您可以创建一个公开数据逻辑的存储库接口,并构建一个在需要的地方注入的MongoDB实现。 这样,MongoDB特定的连接代码就会从您的应用程序中抽象出来,而应用程序只能看到IRepository。

小心尝试使用MongoDB实现工作单元类型模式。 与SQL Server不同,您无法在事务中登记多个查询,如果一个失败,则可以回滚该事务。

有关具有MongoDB,SQL Server和JSON实现的存储库模式的简单示例,请查看NBlog存储代码 。 它使用Autofac IoC将具体的存储库注入ASP.NET MVC应用程序。

如果您对类似于Rob Connery和NBlog存储代码的实现感兴趣,但使用mongodb csharp驱动程序2.0(即异步),您可以查看:

https://github.com/alexandre-spieser/mongodb-generic-repository

然后,您可以编写从BaseMongoRepositoryinheritance的自定义存储库。

 public interface ITestRepository : IBaseMongoRepository { void DropTestCollection(); void DropTestCollection(string partitionKey); } public class TestRepository : BaseMongoRepository, ITestRepository { public TestRepository(string connectionString, string databaseName) : base(connectionString, databaseName) { } public void DropTestCollection() { MongoDbContext.DropCollection(); } public void DropTestCollection(string partitionKey) { MongoDbContext.DropCollection(partitionKey); } }