Шаблон репозитория с MongoDB: где инициализировать базу данных - PullRequest
9 голосов
/ 10 апреля 2011

Я только начал играть с MongoDB (C #) и попытался перенести репозиторий из среды сущностей.Я использую официальный драйвер C # 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...

    }

}

Теперь я хотел бы знать, если это хорошорешение создать такой «контекст» с точки зрения производительности.Имеет ли смысл помещать туда карты BsonClass?Спасибо за ваш вклад.

Ответы [ 3 ]

11 голосов
/ 04 июля 2012
// entity base
public class MongoEntity {
    public ObjectId _id { get; set; }
}

//user entity
public class Users : MongoEntity {
    public string UserName { get; set; }
    public string Password { get; set; }
}


// simple repository
public class Repository {

    private MongoDatabase _db;
    public MongoDatabase Database { get; private set; }
    public Repository(string constr, string dbname) {
        var server = MongoServer.Create(constr);
        _db = server.GetDatabase(dbname);
        Database = _db;
    }

    private MongoCollection<T> GetCollection<T>() where T : MongoEntity {
        return _db.GetCollection<T>(typeof(T).Name);
    }

    public IEnumerable<T> List<T>() where T : MongoEntity {
        return GetCollection<T>().FindAll();
    }

    public IEnumerable<T> List<T>(Expression<Func<T, bool>> exp) where T : MongoEntity {
        return GetCollection<T>().AsQueryable<T>().Where(exp);
    }

    public T Single<T>(Expression<Func<T, bool>> exp) where T : MongoEntity {
        return List<T>(exp).SingleOrDefault();
    }

    public void Insert<T>(T entity) where T : MongoEntity {
        GetCollection<T>().Insert<T>(entity);
    }

    public void Insert<T>(ICollection<T> entities) where T : MongoEntity {
        GetCollection<T>().InsertBatch(entities);
    }

    // Update, Delete method etc ...



}



// example
var repository = new Repository("mongodb://localhost", "test");
repository.Single<Users>(u => u.UserName == "myUserName");
2 голосов
/ 10 апреля 2011

Полагаю, нет смысла регистрировать сопоставление классов каждый раз, когда вы создаете свой класс репозитория. Поскольку драйвер MongoDB C # управляет подключениями к MongoDB внутренне, мне кажется, что лучше создать MongoServer и зарегистрировать сопоставление классов только один раз, во время запуска приложения, а затем использовать его.

Я использую синглтон для создания 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...
    }

}
0 голосов
/ 09 мая 2013

это также интересно, если вы хотите использовать шаблон репозитория.

...