C# 具有ObjectId字符串表示形式的FindOneByIdAs

C# 具有ObjectId字符串表示形式的FindOneByIdAs,c#,mongodb,C#,Mongodb,我对ObjectId表示有一个小问题。 以下是示例代码: public class EntityWithObjectIdRepresentation { public string Id { get; set; } public string Name { get; set; } } [Test] public void ObjectIdRepresentationTest() { BsonClassMap.RegisterClassMap<EntityWith

我对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
}
好的,我包括了项目中的实际代码:

 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);
公共类MongoDbRepository:IRepository
其中T:IEntity//T-实体类型,T2-Id字段类型
{        
受保护的只读MongoCollection集合;
公共MongoDbRepository(MongoDatabase db,string collectionName=null)
{
MongoDbRepositoryConfigurator.EnsureConfigured(db);//调用BsonClassMap.RegisterClassMap,根据需要创建索引
if(string.IsNullOrEmpty(collectionName))
{
collectionName=typeof(T).Name;
}
Collection=db.GetCollection(collectionName);
}
公共T GetById(t2id)
{
使用(Profiler.StepFormat(“MongoDB:{0}.GetById”,Collection.Name))
{
//如何使用FindOneByIdAs
返回Collection.AsQueryable().FirstOrDefault(x=>x.Id.Equals(Id));
}
}
//这里有更多的方法。。。
}
// ...
var repo=new MongoDbRepository();//实际上它是通过DI容器注入的
字符串id=“510a9fe8c87067106c1979de”;
// ...
var entity=repo.GetById(id);
给定地图:

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

使用上述基本逻辑,可以确定成员的序列化类型

如何将泛型存储库类与您的一种类型一起使用?您看过BsonClassMap类的方法和属性了吗。它具有存储的定义。虽然如果您控制数据模型,您可以选择约定而不是配置,默认Id为objectid。这个实现现在使用Linq,但正如我所说的,我希望使用FindById方法,因为它有更好的性能。不,我不想在我的实体中使用ObjectId。(我不是说你会使用ObjectId作为数据类型,只是你的存储库类会假设一个字符串Id实际上映射到一个BSON ObjectId。)超级!成功了。我不知道RepresentationSerializationOptions的演员阵容。现在,我可以将此表示缓存在通用存储库中并使用它。(谢谢)
 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);
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) { ... }