第一部分 基本设计

目前最新版本的C#驱动MongoDB-CSharpDriver-2.2.3,比之前的版本更新比较大,在网上很难找到这个版本的相关C#操作资料,以下都是个人自发研究、测试的,如有雷同,不胜荣幸;如觉不妥,留言喷射;如有错误,还请赐教;如获帮助,示意欣赏。新版中有很多异步操作,本人对此没作研究,怕会产生数据安全问题,所以全部用的是同步方法。

1. 模型设计,使用GUID类型做为Id属性,在初始化时给一个随机值,基类代码,不作解释

using System;using System.Collections.Generic;public interface IEntityBase<T>
    {
        T Id { get;  }
    }
    public abstract class AggregateBase:IEntityBase<Guid>
    {
        public Guid Id { get; private set; }
        public AggregateBase()
        {
            Id = Guid.NewGuid();
        }
    }

2.设计MongoDb的数据上下文类 主要是几个静态方法 代码

using MongoDB.Driver;
using System;

namespace EFAndMongoRepostory
{
    public class MongoDbContext
    {
        private static IMongoDatabase db;
        /// <summary>
        /// 设置并获取数据库
        /// </summary>
        /// <param name="urls">连接地址</param>
        /// <param name="databaseName">数据库名称</param>
        /// <returns></returns>
        public static IMongoDatabase SetMongoDatabase(string urls,string databaseName)
        {
            MongoClient client = new MongoClient(urls);
            db = client.GetDatabase(databaseName);
            return client.GetDatabase(databaseName);
        }
        /// <summary>
        /// 获取数据库中的集合(相当于表)
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        public static IMongoCollection<TEntity> GetMongoCollection<TEntity>(string name)
        {
            IsDbNull();//检测数据库是否存在
            return db.GetCollection<TEntity>(name);
        }
        private static void IsDbNull()
        {
            if (db != null)
                return;
            throw new Exception("the mongodb is null,plese set it on method SetMongoDatabase");
        }
        /// <summary>
        /// 删除集合
        /// </summary>
        /// <param name="name">集合名称</param>
        public static void DropCollection(string name)
        {
            db.DropCollection(name);
        }
    }
}

3.Repostory类设计

1) 使用泛型约束,模拟事务控制,设计相关字段和方法。由于事务控制的是写入操作,我在这里借用MongoDB.Driver中的WriteModel<T>类,将所有写入操作记录在一个list集合中,只要没有发生回滚,并且list中有记录,就可以将所有的写入操作一次性提交,从而达到只与数据库交互一次的目的。具体字段作用看注释

using EFAndMongoRepostory.Entity;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace EFAndMongoRepostory
{
    public class MongoRepostory<TAggregate> where TAggregate :AggregateBase
    {
        /// <summary>
        /// 获取集合
        /// </summary>
        protected IMongoCollection<TAggregate> Collection;
        /// <summary>
        /// 初始化,以类名作为集合名称
        /// </summary>
        /// <param name="collection"></param>
        public MongoRepostory()
        {
            this.Collection = MongoDbContext.GetMongoCollection<TAggregate>(typeof(TAggregate).Name);
        }

        private List<WriteModel<TAggregate>> writers = new List<WriteModel<TAggregate>>();//写入模型集合

        /// <summary>
        /// 指示是否起用事务,默认true
        /// </summary>
        public bool IsUseTransaction { get; set; } = true;

        private bool isRollback = false;//回滚控制
       #region 事务控制
        public void Commit()
        {
            )//如果不回滚,并且writers有数据
                Collection.BulkWrite(writers);
            Rollback();
        }
        public void Rollback()
        {
            writers.Clear();//清空writers
        }
        #endregion
}

3)添加查询数据的方法,由于查询数据基本跟事务没什么关系,可以直接设计一些读数据的方法 代码

using EFAndMongoRepostory.Entity;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace EFAndMongoRepostory
{
    public class MongoRepostory<TAggregate> where TAggregate :AggregateBase
    {
        /// <summary>
        /// 获取集合
        /// </summary>
        protected IMongoCollection<TAggregate> Collection;
        /// <summary>
        /// 初始化,以类名作为集合名称
        /// </summary>
        /// <param name="collection"></param>
        public MongoRepostory()
        {
            this.Collection = MongoDbContext.GetMongoCollection<TAggregate>(typeof(TAggregate).Name);
        }

        private List<WriteModel<TAggregate>> writers = new List<WriteModel<TAggregate>>();//写入模型集合

        /// <summary>
        /// 指示是否起用事务,默认true
        /// </summary>
        public bool IsUseTransaction { get; set; } = true;

        private bool isRollback = false;//回滚控制
       #region 事务控制
        public void Commit()
        {
            )//如果不回滚,并且writers有数据
                Collection.BulkWrite(writers);
            Rollback();
        }
        public void Rollback()
        {
            writers.Clear();//清空writers
        }
        #endregion

 #region 查询
        /// <summary>
        /// 查找所有数据集合
        /// </summary>
        /// <returns></returns>
        public IQueryable<TAggregate> FindAll()
        {
            return Collection.AsQueryable();
        }
        /// <summary>
        /// 根据Id查找一条数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TAggregate FindById(Guid id)
        {
            var find = Collection.Find(o => o.Id == id);
            if (!find.Any())
                return null;
            return find.FirstOrDefault();
        }
        /// <summary>
        /// 根据过滤条件找出符合条件的集合
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public List<TAggregate> FindByFilter(Expression<Func<TAggregate, bool>> filter)
        {
            var find = Collection.Find(filter);
            if (!find.Any())
                return null;
            return find.ToList();
        }
        /// <summary>
        /// 根据过滤条件找出一条数据
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public TAggregate FindOne(Expression<Func<TAggregate, bool>> filter)
        {
            return Collection.Find(filter).FirstOrDefault();
        }
        #endregion
}

4)在每个写入操作的方法中,添加事务控制逻辑,包括是否启用事务逻辑,只要有一个环节发生错误,在提交时便发生回滚,所有操作无效,并不更改数据库中原有的数据。

这里特别提一下的是update操作,这被这个方法困扰了好长好长的时间,企图能在调用端不用引入想关的DLL,只需传入基本的参数就能完成。初步结论是我能力有限,对于lambd表达式还是不够熟,无奈之下,找到一个replace方法代替,发现可用,并且好用,唯一不爽的,你并不能用new()出来的数据作为参数传递,因为你一new,id值就会变,而mongodb中应该也有对于特殊字段名id不能更改的限制。其实再仔细想想逻辑,也应该是不能改变ID值的,因为ID代表着一条数据 的标识,你改变了对于这个数据来说就没有意义了。最后的解决方案是,第一,在方法注释中标注,添加关于这个问题的自定义异常信息。第二,在Update方法注释中,添加提示信息和示例,以防后期忘记相关mongodb的API,两个方法都能用就行。

具体流程控制在部分方法中作了详细注释,发现如果有什么不理解或异议,请留言,将在第一时间作出答复。完整Repostory代码

using EFAndMongoRepostory.Entity;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace EFAndMongoRepostory
{
    public class MongoRepostory<TAggregate> where TAggregate :AggregateBase
    {
        /// <summary>
        /// 获取集合
        /// </summary>
        protected IMongoCollection<TAggregate> Collection;
        /// <summary>
        /// 初始化,以类名作为集合名称
        /// </summary>
        /// <param name="collection"></param>
        public MongoRepostory()
        {
            this.Collection = MongoDbContext.GetMongoCollection<TAggregate>(typeof(TAggregate).Name);
        }

        private List<WriteModel<TAggregate>> writers = new List<WriteModel<TAggregate>>();//写入模型

        /// <summary>
        /// 指示是否起用事务,默认true
        /// </summary>
        public bool IsUseTransaction { get; set; } = true;

        private bool isRollback = false;//回滚控制

        #region 添加
        /// <summary>
        /// 添加一条数据
        /// </summary>
        /// <param name="entity"></param>
        public void Add(TAggregate entity)
        {
            if (entity == null)
                return;
            if (IsUseTransaction)
            {
                try
                {
                    writers.Add(new InsertOneModel<TAggregate>(entity));
                    isRollback = false;//控制是否回滚
                    return;
                }
                catch (Exception ex)
                {
                    isRollback = true;
                    throw new Exception(ex.Message);
                }
            }
            try
            {
                Collection.InsertOne(entity);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        /// <summary>
        /// 添加数据集合
        /// </summary>
        /// <param name="entities"></param>
        public void Add(IEnumerable<TAggregate> entities)
        {
            )
                return;
            if(IsUseTransaction)
            {
                try
                {
                    entities.ToList().ForEach(o =>
                            {
                                writers.Add(new InsertOneModel<TAggregate>(o));
                            });
                    isRollback = false;
                    return;
                }
                catch (Exception ex)
                {
                    isRollback = true;
                    throw new Exception(ex.Message);
                }
            }
            try
            {
                Collection.InsertMany(entities);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        #endregion

        #region 替换
        /// <summary>
        /// 替换一条过滤的数据(请确保此方法Id属性是不能变)
        /// </summary>
        /// <param name="filter">过滤条件</param>
        /// <param name="enity">目标数据(目标数据的Id值必为源数据的Id)</param>
        public void ReplaceOne(Expression<Func<TAggregate, bool>> filter, TAggregate enity)
        {
            if (enity == null)
                return;
            if (IsUseTransaction)
            {
                try
                {
                    writers.Add(new ReplaceOneModel<TAggregate>(Builders<TAggregate>.Filter.Where(filter), enity));
                    isRollback = false;
                    return;
                }
                catch (Exception ex)
                {
                    isRollback = true;
                    throw new Exception(ex.Message);
                }
            }

            try
            {
                Collection.ReplaceOne(filter, enity);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        /// <summary>
        /// 替换一条数据(请确保此方法Id属性是不能变)
        /// </summary>
        /// <param name="id">目标id</param>
        /// <param name="enity">目标数据(目标数据的Id值必为源数据的Id)</param>
        public void ReplaceById(Guid id, TAggregate enity)
        {
            if (enity == null)
                return;
            if(enity.Id!=id)
            {
                isRollback = true;
                throw new Exception("the id can not change");
            }
            if(IsUseTransaction)
            {
                try
                {
                    writers.Add(new ReplaceOneModel<TAggregate>(Builders<TAggregate>.Filter.Eq(o=>o.Id, id), enity));
                    isRollback = false;
                    return;
                }
                catch (Exception ex)
                {
                    isRollback = true;
                    throw new Exception(ex.Message);
                }
            }
            try
            {
                Collection.ReplaceOne(o => o.Id == id, enity);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        /// <summary>
        /// 查找一条数据并且替换
        /// </summary>
        /// <param name="id">目标数据的id</param>
        /// <param name="enity">更改后的数据</param>
        /// <returns>更改前的数据</returns>
        public TAggregate FindOneAndReplace(Guid id, TAggregate enity)
        {
            if (enity == null)
                return null;
            if (enity.Id != id)
            {
                throw new Exception("the id can not change");
            }

            return Collection.FindOneAndReplace(o => o.Id == id, enity);
        }
        /// <summary>
        /// 查找一条数据并且替换
        /// </summary>
        /// <param name="filter">条件</param>
        /// <param name="enity">更改后的数据</param>
        /// <returns>更改前的数据</returns>
        public TAggregate FindOneAndReplace(Expression<Func<TAggregate,bool>>filter, TAggregate enity)
        {
            if (enity == null)
                return null;
            return Collection.FindOneAndReplace(filter, enity);
        }

        #endregion

        #region 移除
        /// <summary>
        /// 根据过滤删除数据
        /// </summary>
        /// <param name="filter"></param>
        public void RemoeMany(Expression<Func<TAggregate, bool>> filter)
        {
            if (IsUseTransaction)
            {
                try
                {
                    writers.Add(new DeleteOneModel<TAggregate>(filter));
                    isRollback = false;
                    return;
                }
                catch (Exception ex)
                {
                    isRollback = true;
                    throw new Exception(ex.Message);
                }
            }
            try
            {
                Collection.DeleteMany(filter);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        public void RemoveById(Guid id)
        {
            if (IsUseTransaction)
            {
                try
                {
                    writers.Add(new DeleteOneModel<TAggregate>(Builders<TAggregate>.Filter.Eq(o => o.Id, id)));
                    isRollback = false;
                    return;
                }
                catch (Exception ex)
                {
                    isRollback = true;
                    throw new Exception(ex.Message);
                }
            }
            try
            {
                Collection.DeleteOne(o => o.Id == id);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        #endregion

        #region 更新
        /// <summary>
        /// 过滤数据,执行更新操作(如不便使用,请用Replace相关的方法代替)
        ///
        /// 一般用replace来代替这个方法。其实这个功能还算强大的,可以很自由修改多个属性
        /// 关健是set参数比较不好配置,并且如果用此方法,调用端必须引用相关的DLL,set举例如下
        /// set = Builders<TAggregate>.Update.Update.Set(o => o.Number, 1).Set(o => o.Description, "002.thml");
        /// set作用:将指定TAggregate类型的实例对象的Number属性值更改为1,Description属性值改为"002.thml"
        /// 说明:Builders<TAggregate>.Update返回类型为UpdateDefinitionBuilder<TAggregate>,这个类有很多静态
        /// 方法,Set()是其中一个,要求传入一个func的表达示,以指示当前要修改的,TAggregate类型中的属性类型,
        /// 另一个参数就是这个属性的值。
        ///
        /// Builders<TAggregate>类有很多属性,返回很多如UpdateDefinitionBuilder<TAggregate>的很有用帮助类型
        /// 可以能参CSharpDriver-2.2.3.chm文件 下载MongoDB-CSharpDriver时带有些文件
        /// 或从官网https://docs.mongodb.com/ecosystem/drivers/csharp/看看
        ///
        /// </summary>
        /// <param name="filter">过滤条件</param>
        /// <param name="set">修改设置</param>
        public void Update(Expression<Func<TAggregate, bool>> filter, UpdateDefinition<TAggregate> set)
        {
            if (set == null)
                return;
            if (IsUseTransaction)//如果启用事务
            {
                try
                {
                    writers.Add(new UpdateManyModel<TAggregate>(filter, set));
                    isRollback = false;//不回滚
                    return;//不执行后继操作
                }
                catch (Exception ex)
                {
                    isRollback = true;
                    throw new Exception(ex.Message);
                }
            }
            try
            {
                Collection.UpdateMany(filter, set);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        /// <summary>
        /// 过滤数据,执行更新操作(如不便使用,请用Replace相关的方法代替)
        ///
        /// 一般用replace来代替这个方法。其实这个功能还算强大的,可以很自由修改多个属性
        /// 关健是set参数比较不好配置,并且如果用此方法,调用端必须引用相关的DLL,set举例如下
        /// set = Builders<TAggregate>.Update.Update.Set(o => o.Number, 1).Set(o => o.Description, "002.thml");
        /// set作用:将指定TAggregate类型的实例对象的Number属性值更改为1,Description属性值改为"002.thml"
        /// 说明:Builders<TAggregate>.Update返回类型为UpdateDefinitionBuilder<TAggregate>,这个类有很多静态
        /// 方法,Set()是其中一个,要求传入一个func的表达示,以指示当前要修改的,TAggregate类型中的属性类型,
        /// 另一个参数就是这个属性的值。
        ///
        /// Builders<TAggregate>类有很多属性,返回很多如UpdateDefinitionBuilder<TAggregate>的很有用帮助类型
        /// 可以能参CSharpDriver-2.2.3.chm文件 下载MongoDB-CSharpDriver时带有些文件
        /// 或从官网https://docs.mongodb.com/ecosystem/drivers/csharp/看看
        ///
        /// </summary>
        /// <param name="id">找出指定的id数据</param>
        /// <param name="set">修改设置</param>
        public void Update(Guid id, UpdateDefinition<TAggregate> set)
        {
            if (set == null)
                return;
            if (IsUseTransaction)//如果启用事务
            {
                try
                {
                    writers.Add(new UpdateManyModel<TAggregate>(Builders<TAggregate>.Filter.Eq(o => o.Id, id), set));
                    isRollback = false;//不回滚
                    return;//不执行后继操作
                }
                catch (Exception ex)
                {
                    isRollback = true;
                    throw new Exception(ex.Message);
                }
            }
            try
            {
                Collection.UpdateMany(o => o.Id == id, set);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
        #endregion

        #region 事务控制
        public void Commit()
        {
            )//如果不回滚,并且writers有数据
                Collection.BulkWrite(writers);
            Rollback();
        }
        public void Rollback()
        {
            writers.Clear();//清空writers
        }
        #endregion

        #region 查询
        /// <summary>
        /// 查找所有数据集合
        /// </summary>
        /// <returns></returns>
        public IQueryable<TAggregate> FindAll()
        {
            return Collection.AsQueryable();
        }
        /// <summary>
        /// 根据Id查找一条数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TAggregate FindById(Guid id)
        {
            var find = Collection.Find(o => o.Id == id);
            if (!find.Any())
                return null;
            return find.FirstOrDefault();
        }
        /// <summary>
        /// 根据过滤条件找出符合条件的集合
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public List<TAggregate> FindByFilter(Expression<Func<TAggregate, bool>> filter)
        {
            var find = Collection.Find(filter);
            if (!find.Any())
                return null;
            return find.ToList();
        }
        /// <summary>
        /// 根据过滤条件找出一条数据
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public TAggregate FindOne(Expression<Func<TAggregate, bool>> filter)
        {
            return Collection.Find(filter).FirstOrDefault();
        }
        #endregion

        /// <summary>
        /// 根据聚合类ID添加导航数据到 导航集合(中间表)
        /// </summary>
        /// <typeparam name="TNav">导航类</typeparam>
        /// <param name="nav">提供参数时直接new一个具体的nav类就行了</param>
        /// <param name="filter"></param>
        /// <param name="foreignKey"></param>
        public void AddByAggregate<TNav>(TNav nav, Expression<Func<TAggregate, bool>> filter, Guid foreignKey)
                                        where TNav : NavgationBase
        {
            //导航类的集合
            var navCollection = MongoDbContext.GetMongoCollection<TNav>(typeof(TNav).Name);
            //遍历当前集合中所有符合条件的数据
            Collection.Find(filter).ToList().ForEach(o =>
            {
                //将导航类的属性赋相应的值
                nav.AggregateId = foreignKey;
                nav.ValueObjectId = o.Id;

                //插入到数据库
                navCollection.InsertOne(nav);
            });
        }

    }
}

5)截个图

6)Repostory类完成  是的,你可能在最后部分发现了一个额外的方法,这个方法是需要一个泛型参数,我理想的作用是用来配置集合(数据表)之关的多对多关系的,这也是仿EF中的通过一个中间表来实现,那么Model的设计就要改造一下了。另外我还有一个想法就是想设计专门针对聚合根中值类型的操作,但是这些还没有完成,时间太晚了,以后再慢慢搞起。可以看看现在model的设计,这里面没有分层,因我是在控制台下做测试的。另外添加了几个实现类,以备下次测试 ,没有注释,接口设计都还不完善,但是对事务部分的CURD没影响,现阶段model代码

using System;
using System.Collections.Generic;

namespace EFAndMongoRepostory.Entity
{
    public interface IEntityBase<T>
    {
        T Id { get;  }
    }
    public abstract class AggregateBase:IEntityBase<Guid>
    {
        public Guid Id { get; private set; }
        public AggregateBase()
        {
            Id = Guid.NewGuid();
        }
    }
    public interface IValueObject
    {
        Guid Id { get;  }
    }
    public abstract class ValueObjectBase
    {
        public Guid Id { get;}

        public ValueObjectBase()
        {
            Id = Guid.NewGuid();
        }
    }
    public abstract class NavgationBase
    {
        public virtual Guid AggregateId { get; set; }
        public virtual Guid ValueObjectId { get; set; }
    }
    public class User : AggregateBase
    {
        public string Name { get; set; }
        public string Pwd { get; set; }
        public int Number { get; set; }
        public ICollection<Role> Roles { get; set; } = new List<Role>();
        public ICollection<Permission> Permissions { get; set; } = new List<Permission>();
    }

    public class Role :AggregateBase, IValueObject
    {
        public int Number { get; set; }
        public Guid UserGId { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public ICollection<Permission> Permissions { get; set; } = new List<Permission>();
    }

    public class Permission:ValueObjectBase
    {
        public Guid UserId { get; set; }
        public Guid RoleId { get; set; }
        public string Name { get; set; }
        public string Url { get; set; }
        public bool HavePermission { get; set; } = true;
    }
    public class User_Role : NavgationBase
    {
    }
    public class Role_Permission : NavgationBase
    {
    }
    public class User_Permission : NavgationBase
    {
    }
}

4.客户端测试 这里用的是控制台,而没有写测试代码,感觉这样跟写单元测试也没多大的区别。当然了,还是应该写单元测试的,起码代码复用高。Repostory设计好了,调用就简单了,我已经做过了部分测试,所以代码都是注释状态,如果你也想做测试,一步步的释放注释试试。代码

using EFAndMongoRepostory;
using EFAndMongoRepostory.Entity;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;

namespace MongoTest
{
    class Program
    {
        static void Main(string[] args)
        {

            #region 初始化
            //MongoClient client = new MongoClient("mongodb://localhost:27017");   //mongo客户端
            //var db = client.GetDatabase("MongoTest");                            //数据库
            var db = MongoDbContext.SetMongoDatabase("mongodb://localhost:27017", "MongoTest");
            #endregion

            #region 准备数据
            List<Role> rList = new List<Role>
                    {
                        new Role
                        {
                            Name="r001", Description="rd001"
                        },
                        new Role
                        {
                            Name="r002",Description="rd002"
                        },
                        new Role
                        {
                            Name="r003",Description="rd003"
                        }
                    };
            List<User> uList = new List<User>
            {
                new User
                {
                    Name=", Pwd="pwd001"
                },
                new User
                {
                    Name=",  Pwd="pwd002"
                }
                ,
                new User
                {
                    Name=", Pwd="pwd003"
                }
                ,
                new User
                {
                    Name=", Pwd="pwd004"
                }
            };
            List<Permission> pList = new List<Permission>
            {
                 ", Url="001.html" },
                 ", Url="002.html" },
                 ", Url="003.html" },
                 ", Url="004.html" },
                 ", Url="005.html" }
            };
            #endregion

            var repostory = new MongoRepostory<User>();
            //插入几条测试数据
            //repostory.Add(uList);
            //repostory.Commit();

            //测试替换操作
            //var user = repostory.FindOne(o => o.Name == "001");
            //user.Pwd = "password001";
            //repostory.ReplaceById(user.Id, user);
            //repostory.Commit();
            //Console.WriteLine(user.Name + ":" + user.Pwd);

            //测试更新操作
            //var set = Builders<User>.Update.Set(o => o.Pwd, "pwd001").Set(o => o.Name, "01111");
            //repostory.Update(user.Id, set);
            //repostory.Commit();
            //Console.WriteLine(user.Name + ":" + user.Pwd);

            //测试替换前后数据
            //var user = repostory.FindOne(o => o.Name == "01111");
            //user.Name = "001";
            //user = repostory.FindOneAndReplace(user.Id, user);

            //var u2 = repostory.FindById(user.Id);

            //Console.WriteLine(user.Name + ":" + user.Pwd);
            //Console.WriteLine("替换后的");
            //Console.WriteLine(u2.Name + ":" + u2.Pwd);

            var query = repostory.FindAll().ToList();
            query.ForEach(o => {
                Console.WriteLine(o.Name + ":" + o.Pwd);
            });
            Console.ReadKey();
        }

    }

}

5.关于门外汉和OADemo 之所以说是门外汉,是因为我没有从事过软件开发工作,都是业余时间学习的。而正是基于此,之前写的OADemo我也觉得应该放了,毕竟没做过真实项目,现在园子里有一个很火的关于mvc的精彩连续剧 ,专业,详细。如果有关注我之前的OADemo可以移步关注。我写这个的目的除了很少一部分是备忘,更大一部分是来自虚荣心,我也希望能得到关注,肯定。其实本来是想在Domain层完成权限块的,也不知怎么的就关注到MongoDB这来了,还真是不专心啊。

打住了,再发到首页去看看,能不能通过,已经两篇心血被下架了,还过不了就严重受打击了。

看门外汉如何实现:C#操作 MongoDB基本CURD的事务控制的更多相关文章

  1. 看门外汉如何实现:C#操作 MongoDB基本CURD的事务控制之 第二部分

    第二部分 尝试解决BulkWrite(List<WriteModel<T>>)问题 在上次发表的文章中,得到了一些很好的反馈,真切体会到写博文的好处,有高人指出两大问题,具体可 ...

  2. Python操作MongoDB看这一篇就够了

    MongoDB是由C++语言编写的非关系型数据库,是一个基于分布式文件存储的开源数据库系统,其内容存储形式类似JSON对象,它的字段值可以包含其他文档.数组及文档数组,非常灵活.在这一节中,我们就来看 ...

  3. JAVA操作MongoDB数据库

    1. 首先,下载MongoDB对Java支持的驱动包 驱动包下载地址:https://github.com/mongodb/mongo-java-driver/downloads 2.Java操作Mo ...

  4. 学习MongoDB--(11):应用举例(利用java操作MongoDB)

    原文地址:http://blog.csdn.net/drifterj/article/details/7948090 目录地址:http://blog.csdn.net/DrifterJ/articl ...

  5. Mongodb快速入门之使用Java操作Mongodb

    [IT168 专稿]在上一篇文章中,我们学习了Mongodb的安装和初步使用,在本文中,将学习如何使用Java去编程实现对Mongodb的操作. HelloWorld程序 学习任何程序的第一步,都是编 ...

  6. node.js高效操作mongodb

    node.js高效操作mongodb Mongoose库简而言之就是在node环境中操作MongoDB数据库的一种便捷的封装,一种对象模型工具,类似ORM,Mongoose将数据库中的数据转换为Jav ...

  7. MongoDB的安装与python操作MongoDB

    一.安装MongoDB 因为我个人使用的是windows,就只记录下windows下的安装 1.下载安装 就是官网,下载msi,选个路径安装 2.配置 看见别的地方说需要手动在bin同级目录创建dat ...

  8. Node操作MongoDB并与express结合实现图书管理系统

    Node操作MongoDB数据库 原文链接:http://www.xingxin.me/ Web应用离不开数据库的操作,我们将陆续了解Node操作MongoDB与MySQL这是两个具有代表性的数据库, ...

  9. java操作mongodb(连接池)(转)

    原文链接: java操作mongodb(连接池) Mongo的实例其实就是一个数据库连接池,这个连接池里默认有10个链接.我们没有必要重新实现这个链接池,但是我们可以更改这个连接池的配置.因为Mong ...

随机推荐

  1. JQuery插件让图片旋转任意角度且代码极其简单

    引入下方的jquery.rotate.js文件,然后通过$("选择器").rotate(角度);可以旋转任意角度, 例如$("#rotate-image").r ...

  2. Effective STL(第7条)

    第7条:如果容器中包含了通过new操作创建的指针,切忌在容器对象析构前将指针delete掉 //向一个vector中添加多个new出来的对象 void doSomething(){ vector< ...

  3. jQuery cdn使用介绍

    如果您不希望下载并存放jQuery,那么也可以通过 CDN(内容分发网络)引用它,下面是具体实现,有类似需求的各位可以参考下哈,希望对你有所帮助   如果您不希望下载并存放 jQuery,那么也可以通 ...

  4. 配置RAC到单节点standby的data guard

    1RAC主库准备 2创建物理备库 3主库调整参数 4测试DG

  5. 使用dd制作文件夹的img

    du -sh originfile //先看看需要制作的源文件夹大小,假如15M dd if=/dev/zero of=new_img.img bs=1024 count=20000 //生成20M的 ...

  6. CSS权威指南 - 基础视觉格式化 3

    行内替换元素 替换元素比如图片的高度比line-height大,并不会影响整个文字段落的line-height,会让有图片那一行框的高度可以容纳这个图片. 这个图片依然有一个line-height,和 ...

  7. 精通JavaScript的this关键字

    小提示 阅读本文,您需要了解JS的基本常识.您将花费40分钟完成本文的阅读. JS中的this关键字让很多新老JS开发人员都感到困惑.这篇文章将对this关键字进行完整地阐述.读完本文以后,您的困惑将 ...

  8. window.self ->window.top->window.parent

    在应用有frameset或者iframe的页面时,parent是父窗口,top是最顶级父窗口(有的窗口中套了好几层frameset或者iframe),self是当前窗口, opener是用open方法 ...

  9. JQuery-属性

    // attr能访问到的都是html里面的样式,诸如内联样式.外部样式和外联样式该方法访问不到 $('#div1').width('400px') // 这个用来改样式css $("#div ...

  10. XE5 ImageList的BUG?

    今天做界面, 在imagelist里加载一个带有半透明通道的PNG图, 结果发现图片居然发暗, 如下: 原图: IDE里加载以后的图: 明显变暗...查询了源码, 无果 然后又用2010去测试, 发现 ...