2013-02-01 87 views
0

我有一個ObjectId表示的小問題。 下面是示例代碼:FindOneByIdAs ObjectId的字符串表示形式

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)); 

但我想要的是抽象的東西,這在一般的庫類,所以一般我不知道這是否標識必須轉換爲ObjectId或不轉換。 我可以從BsonClassMap中檢索這些信息嗎?

下面的代碼工作過,但由於LINQ表達皈依,它幾乎是在慢15倍,根據基準:

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

OK,我包括項目的實際代碼:

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爲objectid。 – WiredPrairie

+0

我已經添加了代碼。這個實現現在正在使用Linq,但正如我所說的,我想使用FindById方法,因爲它具有更好的性能。不,我不想在我的實體中使用ObjectId。 – VirusX

+0

(我不是說你會使用ObjectId作爲數據類型,只是你的存儲庫類會假定字符串Id實際映射到BSON ObjectId。) – WiredPrairie

回答

1

給定地圖:

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) { ... } 

使用上面的基本邏輯,您可以確定se rialized類型的成員。

+0

超級!有效。我不知道有關RepresentationSerializationOptions強制轉換。現在我可以在通用資源庫中緩存這個表示並使用它。謝謝) – VirusX

相關問題