C# MongoDB的存储库模式:在何处初始化数据库

C# MongoDB的存储库模式:在何处初始化数据库,c#,mongodb,repository-pattern,C#,Mongodb,Repository Pattern,我刚开始使用MongoDB(C#),并尝试从实体框架移植存储库。我正在使用官方的C#driver 1.0。现在我做了这样的事情: internal class MongoContext { public MongoContext(string constring) { MongoServer server = MongoServer.Create(constring); this.myDB = server.GetDatabase("MyDB");

我刚开始使用MongoDB(C#),并尝试从实体框架移植存储库。我正在使用官方的C#driver 1.0。现在我做了这样的事情:

internal class MongoContext
{
    public MongoContext(string constring)
    {
        MongoServer server = MongoServer.Create(constring);
        this.myDB = server.GetDatabase("MyDB");

        BsonClassMap.RegisterClassMap<VoyageNumber>(cm =>
            { cm.MapField<string>(p => p.Id); });
        BsonClassMap.RegisterClassMap<Schedule>(cm =>
        { cm.MapField<DateTime>(p => p.EndDate); cm.MapField<DateTime>(p => p.StartDate); });
        BsonClassMap.RegisterClassMap<Voyage>(cm =>
            { cm.MapIdField<VoyageNumber>(p => p.VoyageNumber); cm.MapField<Schedule>(p => p.Schedule); });

    }

    private MongoDatabase myDB;
    public MongoDatabase MyDB
    { get { return this.myDB; } }
}
public class MongoVoyageRepository : IVoyageRepository
{
    private readonly MongoContext context;

    public MongoVoyageRepository(string constring)
    {
        this.context = new MongoContext(constring);
    }

    public void Store(Domain.Model.Voyages.Voyage voyage)
    {

        MongoCollection<Voyage> mongoVoyages = context.MyDB.GetCollection<Voyage>("Voyages");

        //store logic...

    }

}
内部类MongoContext
{
公共MongoContext(字符串构造)
{
MongoServer服务器=MongoServer.Create(constring);
this.myDB=server.GetDatabase(“myDB”);
BsonClassMap.RegisterClassMap(cm=>
{cm.MapField(p=>p.Id);});
BsonClassMap.RegisterClassMap(cm=>
{cm.MapField(p=>p.EndDate);cm.MapField(p=>p.StartDate);});
BsonClassMap.RegisterClassMap(cm=>
{cm.MapIdField(p=>p.VoyageNumber);cm.MapField(p=>p.Schedule);});
}
私有MongoDatabase myDB;
公共MongoDatabase MyDB
{get{返回this.myDB;}}
}
然后,我将继续实现存储库,如下所示:

internal class MongoContext
{
    public MongoContext(string constring)
    {
        MongoServer server = MongoServer.Create(constring);
        this.myDB = server.GetDatabase("MyDB");

        BsonClassMap.RegisterClassMap<VoyageNumber>(cm =>
            { cm.MapField<string>(p => p.Id); });
        BsonClassMap.RegisterClassMap<Schedule>(cm =>
        { cm.MapField<DateTime>(p => p.EndDate); cm.MapField<DateTime>(p => p.StartDate); });
        BsonClassMap.RegisterClassMap<Voyage>(cm =>
            { cm.MapIdField<VoyageNumber>(p => p.VoyageNumber); cm.MapField<Schedule>(p => p.Schedule); });

    }

    private MongoDatabase myDB;
    public MongoDatabase MyDB
    { get { return this.myDB; } }
}
public class MongoVoyageRepository : IVoyageRepository
{
    private readonly MongoContext context;

    public MongoVoyageRepository(string constring)
    {
        this.context = new MongoContext(constring);
    }

    public void Store(Domain.Model.Voyages.Voyage voyage)
    {

        MongoCollection<Voyage> mongoVoyages = context.MyDB.GetCollection<Voyage>("Voyages");

        //store logic...

    }

}
公共类MongoVoyageRepository:IVoyageRepository
{
私有只读MongoContext上下文;
公共MongoVoyageRepository(字符串构造)
{
this.context=新的MongoContext(解释);
}
公共void存储(Domain.Model.Voyages.Voyages)
{
MongoCollection mongoVoyages=context.MyDB.GetCollection(“航行”);
//存储逻辑。。。
}
}
现在我想知道在性能方面实例化这样的“上下文”是否是一个好的决定。把BsonClass映射放在那里有意义吗?
谢谢您的输入。

我想在每次创建存储库类时注册类映射是没有意义的。由于MongoDB C#驱动程序在内部管理与MongoDB的连接,在我看来,最好在应用程序启动期间创建
MongoServer
并只注册一次类映射,然后使用它

我使用singleton是为了只创建一次
MongoServer

public class MongoRead : MongoBase
{
  public MongoRead(MongoServer server)
            : base(server)
  {

  }


  public override MongoDatabase Database
  {
     get { return Server.GetDatabase("myDb"); }
  }

  public MongoCollection Logs
  {
    get { return Database.GetCollection("logs"); }
  }

  private static MongoRead _instance = null;

  public static MongoRead Instance
  {
    get
      {
        if (_instance == null)
        {
          _instance = RegisterMongoDb();

        }

        return _instance;
      }

  }

  private static MongoRead RegisterMongoDb()
  {
      var readServer = MongoServer.Create(connectionString);
      var read = new MongoRead(readServer);

      var myConventions = new ConventionProfile();
      myConventions.SetIdMemberConvention(new NoDefaultPropertyIdConvention());
      BsonClassMap.RegisterConventions(myConventions, t => true);

      return read;
  }

}
因此,您还可以在存储库中使用上述类:

public class MongoVoyageRepository : IVoyageRepository
{
    private readonly MongoRead context
    {
      get { return MongoRead.Instance; }
    };

    public MongoVoyageRepository()
    {
    }

    public void Store(Domain.Model.Voyages.Voyage voyage)
    {
            MongoCollection<Voyage> mongoVoyages = 
                  context.Database.GetCollection<Voyage>("Voyages");
            //store logic...
    }

}
公共类MongoVoyageRepository:IVoyageRepository
{
私有只读MongoRead上下文
{
获取{return MongoRead.Instance;}
};
公共MongoVoyageRepository()
{
}
公共void存储(Domain.Model.Voyages.Voyages)
{
MongoCollection mongoVoyages=
context.Database.GetCollection(“Voyages”);
//存储逻辑。。。
}
}
//实体库
公共类MongoEntity{
公共对象id{get;set;}
}
//用户实体
公共类用户:MongoEntity{
公共字符串用户名{get;set;}
公共字符串密码{get;set;}
}
//简单存储库
公共类存储库{
私有MongoDatabase_db;
公共MongoDatabase数据库{get;private set;}
公共存储库(string constr、string dbname){
var server=MongoServer.Create(constr);
_db=server.GetDatabase(dbname);
数据库=_db;
}
私有MongoCollection GetCollection(),其中T:MongoEntity{
return _db.GetCollection(typeof(T).Name);
}
public IEnumerable List(),其中T:MongoEntity{
返回GetCollection().FindAll();
}
公共IEnumerable列表(表达式exp),其中T:MongoEntity{
返回GetCollection().AsQueryable().Where(exp);
}
公共T单个(表达式exp),其中T:MongoEntity{
返回列表(exp).SingleOrDefault();
}
公共无效插入(T实体),其中T:MongoEntity{
GetCollection().Insert(实体);
}
公共空白插入(ICollection实体),其中T:MongoEntity{
GetCollection().InsertBatch(实体);
}
//更新、删除方法等。。。
}
//范例
var repository=新存储库(“mongodb://localhost“,”测试“);
repository.Single(u=>u.UserName==“myUserName”);

如果您想使用存储库模式,这也很有趣。

这是可行的,但我已经将实例属性转换为一个接受连接字符串的方法,因为我想将连接字符串注入存储库(IoC)。@Malkier:I也使用IoC adn DI,刚刚制作了
实例
,因为许多开发人员不了解IoC、DI,或者很难理解;)@AndrewOrsich什么是类
NoDefaultPropertyIdConvention