我有一个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);
你将如何使用通用资源库类与您的类型之一?你看过BsonClassMap类的方法和属性吗? http://api.mongodb.org/csharp/1.0/html/18aadb76-2494-c732-9768-bc9f41597801.htm。它具有存储的定义。尽管如果你在控制数据模型,你可以选择约定而不是配置,默认为Id为objectid。 – WiredPrairie
我已经添加了代码。这个实现现在正在使用Linq,但正如我所说的,我想使用FindById方法,因为它具有更好的性能。不,我不想在我的实体中使用ObjectId。 – VirusX
(我不是说你会使用ObjectId作为数据类型,只是你的存储库类会假定字符串Id实际映射到BSON ObjectId。) – WiredPrairie