0

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

しかし、私が欲しいのは、ジェネリックリポジトリクラスでこのようなものを抽象化することです。したがって、一般的に、この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);
4

1 に答える 1

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

上記の基本的なロジックを使用して、メンバーのシリアル化された型を判断できます。

于 2013-02-01T13:46:06.953 に答える