2011-04-10 2 views
9

방금 ​​MongoDB (C#)로 시작하여 엔터티 프레임 워크에서 저장소를 포팅하려고했습니다. 공식 C# 드라이버 1.0을 사용하고 있습니다.MongoDB를 사용한 저장소 패턴 : 데이터베이스 초기화 위치

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 맵을 두는 것이 이치에 맞습니까? 입력 해 주셔서 감사합니다.

답변

2

저장소 클래스를 만들 때마다 매핑 할 클래스를 등록하는 것이 좋습니다. MongoDB C# 드라이버는 내부적으로 MongoDB에 대한 연결을 관리하기 때문에 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; 
    } 

} 

그래서 당신은 또한 당신의 저장소에 클래스 이상 사용할 수있는 한 번만 MongoServer을 만들 싱글을 사용하고 있습니다 : 당신이 원하는 경우

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

작동하지만 저장소 문자열 (IoC)에 연결 문자열을 주입하려고하므로 연결 문자열을 받아들이는 메서드로 Instance 속성을 변형했습니다. – hoetz

+0

@Malkier : 또한 IoC adn DI를 사용합니다. 많은 개발자가 IoC, DI 또는 undestand에 대해 알지 못하기 때문에 인스턴스 만 만들었습니다.) –

+0

@AndrewOrsich 'NoDefaultPropertyIdConvention' 클래스는 무엇입니까? –

11
// 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"); 
0

this도 흥미 롭다 저장소 패턴을 사용합니다.