MongoDB中和C#的工作单位 [英] Unit of work in mongodb and C#

查看:123
本文介绍了MongoDB中和C#的工作单位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道MongoDB是不应该支持工作等的单位,但我认为这将是很好的落实,因为这只会存储意图(类似标准),然后将其提交到数据库存储库。否则,在你的资料库中的每个方法,你必须创建连接数据库,然后将其关闭。如果我们把一些BaseRepository类数据库连接,然后我们配合我们的代码库到具体的DB,这是真的很难测试库,测试的IoC其决心库。



是建立在MongoDB中一个会话一个坏主意?有没有一种方法可以区分库中的连接逻辑?



下面是一些代码由罗布科纳。它是一个好主意,总是连接到您的数据库在每次请求?什么是最好的做法是什么?



有一件事情。想象一下,我想为一个集合的索引。以前我在做一个构造函数,但与Rob的做法,这似乎从逻辑做它。

 使用规范;使用Norm.Responses 
;使用Norm.Collections
;
使用Norm.Linq;

公共类MongoSession {

私人字符串_connectionString;

公共MongoSession(){
//根据需要设置此连接。这是离开这里,作为一个例子,但你可以,如果你想,
_connectionString =:;MongoDB的//127.0.0.1/MyDatabase严格=假的?
}

公共无效删除< T>(System.Linq.Expressions.Expression< Func键< T,BOOL>>表达式)其中T:类,新的(){
//效率不高,规范应在发出一个命令的MongoDB的方式做到这一点。
VAR项目=所有< T>(),其中(表达)。
的foreach(在项目牛逼项){
删除(项目);
}
}

公共无效删除< T>(T项目),其中T:类,新的(){
使用(VAR DB = Mongo.Create( _connectionString))
{
db.Database.GetCollection< T>()删除(项目)。
}
}

公共无效DeleteAll< T>()其中T:类,新的(){使用
(VAR DB = Mongo.Create(_connectionString) )
{
db.Database.DropCollection(typeof运算(T).Name点);
}
}

公共T单< T>(System.Linq.Expressions.Expression< Func键< T,BOOL>>表达式)其中T:类,新( ){$ b $(b T)= RETVAL默认(T);使用
(VAR DB = Mongo.Create(_connectionString))
{
RETVAL = db.GetCollection< T>()AsQueryable已()
。凡(表达).SingleOrDefault ();
}
返回RETVAL;
}

公众的IQueryable< T>所有< T>()其中T:类,新的(){
//比你需要它不保持这种更长的时间。
变种DB = Mongo.Create(_connectionString);
返回db.GetCollection< T>()AsQueryable已()。
}

公共无效添加< T>(T项目),其中T:类,新的(){
使用(VAR DB = Mongo.Create(_connectionString))
{
db.GetCollection< T>()插入(项目);
}
}

公共无效添加< T>(IEnumerable的< T>项目),其中T:类,新的(){
//这是远远快不是做单一的刀片。使用
(VAR DB = Mongo.Create(_connectionString))
{
db.GetCollection< T>()插入(项目)。
}
}

公共无效更新< T>(T项目),其中T:类,新的(){
使用(VAR DB = Mongo.Create( _connectionString))
{
db.GetCollection< T>()UpdateOne(项目,项目)。
}
}

//这只是一些糖,如果你需要它。
公共牛逼的MapReduce< T>(字符串映射,串减少){$ B $(B T)结果=默认(T);使用
(VAR DB = Mongo.Create(_connectionString))
{
VAR MR = db.Database.CreateMapReduce();
MapReduceResponse响应=
mr.Execute(新MapReduceOptions(typeof运算(T).Name点){
=地图地图,
=减少减少
});
MongoCollection< MapReduceResult< T>>科尔= response.GetCollection< MapReduceResult< T>>();
MapReduceResult< T> R = coll.Find()FirstOrDefault()。
结果= r.Value;
}
返回结果;
}

公共无效的Dispose(){
_server.Dispose();
}
}


解决方案

唐T过分担心打开和关闭连接。 MongoDB的C#驱动程序维护的内部连接池,这样你就不会遭受开幕,并在每次创建时关闭实际连接的开销一个新的 MongoServer 对象。



您可以创建一个存储库接口暴露你的数据逻辑,并构建它需要的地方被注入了MongoDB的实现。这样一来,MongoDB的连接特定的代码是从您的应用程序,它只能看到IRepository abstratced了。



小心试图执行一个单位的工作类型模式MongoDB的。与SQL Server不同,你不能争取在一个事务中的多个查询,如果其中一个出现故障,可以回滚。



对于具有MongoDB的存储库模式的一个简单的例子, SQL Server和JSON的实现,请查看 NBlog存储代码。它采用 Autofac 的IoC注入混凝土仓库到ASP.NET MVC应用程序。


I know that MongoDB is not supposed to support unit of work, etc. But I think it would be nice to implement the repository which would store only the intentions (similar to criteria) and then commit them to the DB. Otherwise in every method in your repository you have to create connection to DB and then close it. If we place the connection to DB in some BaseRepository class, then we tie our repository to concrete DB and it is really difficult to test repositories, to test IoC which resolve repositories.

Is creating a session in MongoDB a bad idea? Is there a way to separate the connection logic from repository?

Here is some code by Rob Conery. Is it a good idea to always connect to your DB on every request? What is the best practice?

There is one more thing. Imagine I want to provide an index for a collection. Previously I did in a constructor but with Rob's approach this seems out of logic to do it there.

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

解决方案

Don't worry too much about opening and closing connections. The MongoDB C# driver maintains an internal connection pool, so you won't suffer overheads of opening and closing actual connections each time you create a new MongoServer object.

You can create a repository interface that exposes your data logic, and build a MongoDB implementation that is injected where it's needed. That way, the MongoDB specific connection code is abstratced away from your application, which only sees the IRepository.

Be careful trying to implement a unit-of-work type pattern with MongoDB. Unlike SQL Server, you can't enlist multiple queries in a transaction that can be rolled back if one fails.

For a simple example of a repository pattern that has MongoDB, SQL Server and JSON implementations, check out the NBlog storage code. It uses Autofac IoC to inject concrete repositories into an ASP.NET MVC app.

这篇关于MongoDB中和C#的工作单位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆