2013-02-01 1 views
0

ObjectId 표현에 약간의 문제가 있습니다. 여기 샘플 코드 :ObjectId 문자열 표현이있는 FindOneByIdAs

public class EntityWithObjectIdRepresentation 
{ 
    public string Id { get; set; } 

    public string Name { get; set; } 
} 

[Test] 
public void ObjectIdRepresentationTest() 
{ 
    BsonClassMap.RegisterClassMap<EntityWithObjectIdRepresentation>(cm => 
    { 
     cm.AutoMap(); 
     cm.GetMemberMap(x => x.Id).SetRepresentation(BsonType.ObjectId); 
    }); 

    var col = db.GetCollection("test"); 
    var entity = new EntityWithObjectIdRepresentation(); 
    col.Insert(entity); 

    Assert.IsNotNullOrEmpty(entity.Id); // Ok, Id is generated automatically 

    var res = col.FindOneByIdAs<EntityWithObjectIdRepresentation>(entity.Id); 
    Assert.IsNotNull(res); // Fails here 
} 

위의 코드는

var res = col.FindOneByIdAs<EntityWithObjectIdRepresentation>(ObjectId.Parse(entity.Id)); 

와 잘 작동하지만 내가 원하는 것은 그래서 일반적으로 나도 몰라 일반 저장소 클래스 추상이 물건이다이 ID 여부 ObjectId로 변환해야하는지 여부. BsonClassMap에서 이러한 정보를 검색 할 수 있습니까?

다음 코드는 거의 15 배 느린 벤치 마크에 따라 때문에 LINQ 표현 convertion 너무 작동하지만 :

public class MongoDbRepository<T, T2> : IRepository<T, T2> 
    where T : IEntity<T2> // T - Type of entity, T2 - Type of Id field 
{   
    protected readonly MongoCollection<T> Collection; 

    public MongoDbRepository(MongoDatabase db, string collectionName = null) 
    { 
     MongoDbRepositoryConfigurator.EnsureConfigured(db); // Calls BsonClassMap.RegisterClassMap, creates indexes if needed 

     if (string.IsNullOrEmpty(collectionName)) 
     { 
      collectionName = typeof(T).Name; 
     } 

     Collection = db.GetCollection<T>(collectionName); 
    } 

    public T GetById(T2 id) 
    { 
     using (Profiler.StepFormat("MongoDB: {0}.GetById", Collection.Name)) 
     { 
      // TODO Use FindOneByIdAs<T> 
      return Collection.AsQueryable().FirstOrDefault(x => x.Id.Equals(id)); 
     } 
    } 

    // some more methods here ... 
} 

// ... 
var repo = new MongoDbRepository<SomeEntity,string>(); // Actually it's injected via DI container 
string id = "510a9fe8c87067106c1979de"; 

// ... 
var entity = repo.GetById(id); 
+0

유형 중 하나와 함께 제네릭 리포지토리 클래스를 어떻게 사용 하시겠습니까? BsonClassMap 클래스 메서드와 속성을 살펴 보았습니까? http://api.mongodb.org/csharp/1.0/html/18aadb76-2494-c732-9768-bc9f41597801.htm. 저장된 정의가 있습니다. 비록 당신이 데이터 모델을 제어하고 있다면 컨피규레이션에 대한 관례를 선택할 수 있으며, ID는 객체 ID가된다. – WiredPrairie

+0

코드를 추가했습니다. 이 구현은 현재 Linq를 사용하고 있지만 필자가 말했듯이 FindById 메소드는 성능이 훨씬 뛰어나다. 그리고 아니, 내 개체에서 ObjectId를 사용하고 싶지 않습니다. – VirusX

+0

(데이터 유형으로 ObjectId를 사용한다는 의미는 아니며 리포지토리 클래스는 실제로 문자열 ID가 BSON ObjectId에 매핑되었다고 가정합니다.) – WiredPrairie

답변

1
:

var res = col.AsQueryable().FirstOrDefault(x => x.Id.Equals(id)); 

OK, I 프로젝트에서 실제 코드를 포함하고있어

이지도 감안할 때 :

var classmap = BsonClassMap.LookupClassMap(typeof(T)); 
// // This is an indexed array of all members, so, you'd need to find the Id 
var member = map.AllMemberMaps[0]; 
var serOpts = ((RepresentationSerializationOptions).SerializationOptions); 
if (serOpts.Representation == BsonType.ObjectId) { ... } 

위의 기본 논리를 사용하여, 당신은 그 자체로 확인할 수 있습니다 회원의 유료화 된 유형.

+0

Super! 그것은 효과가 있었다. RepresentationSerializationOptions 캐스트에 대해 몰랐습니다. 이제이 표현을 일반 저장소에 캐시하여 사용할 수 있습니다. 감사) – VirusX

관련 문제