用于C#类层次结构的MongoDB顺序int id生成器

时间:2019-01-28 14:46:40

标签: c# mongodb id-generation

我有一个带有单独的BsonClass映射的C#类层次结构。我所有的类都使用自定义顺序int id生成。最后一个ID存储在称为“计数器”的特殊集合中。我的问题是当引发诸如InvalidCastException之类的InsertInAsync之类的mongo收集方法时。

基础实体类:

public getselectedCategory(){
    this.sortService.CategoryObjectOut.subscribe(val=>{
      for(let i =0; i< this.categoriesTree.length;i++){
        if(this.categoriesTree[i] == val.node){
          this.selectedCategory=val
          return this.selectedCategory.node;
        }
      }
    })
  }

儿童班:

[selected]="categoriesTree[0]"

基类图:

[Serializable]
public abstract class Entity<TIdentifier> : IEntity<TIdentifier>
{
    public TIdentifier Id { get; set; }

    public DateTime CreatedDate { get; set; }

    public DateTime UpdatedDate { get; set; }

    public virtual bool IsTransient()
    {
        return (object) this.Id == null || this.Id.Equals((object) default (TIdentifier));
    }
}

儿童班级地图:

public class Child : Entity<int> 
{
    public int SomeData { get; set; }
}

顺序int id生成器类:

public class EntityMap
{
    public static void Register()
    {
        BsonClassMap.RegisterClassMap<Entity<int>>(cm =>
        {
            cm.AutoMap();
            cm.MapIdProperty(c => c.Id)
                .SetIdGenerator(SeqIntIdGenerator<Entity<int>>.Instance)
                .SetSerializer(new Int32Serializer(BsonType.Int32));
        });
    }
}
将容器从Object投射到IMongoCollection时抛出

InvalidCastException。怎么做对?我的C#驱动程序版本是2.7.2。

2 个答案:

答案 0 :(得分:1)

如果您已经在使用动态,则可以为此切换反射代码>

public object GenerateId(object container, object document)
{
    var containerDynamic = (dynamic) container;
    var idSequenceCollection = containerDynamic.Database.GetCollection<dynamic>("Counters");

    var filter = Builders<dynamic>.Filter.Eq("_id", containerDynamic.CollectionNamespace.CollectionName);
    var update = Builders<dynamic>.Update.Inc("Seq", 1);

    var options = new FindOneAndUpdateOptions<dynamic>
    {
        IsUpsert = true,
        ReturnDocument = ReturnDocument.After
    };

    return idSequenceCollection.FindOneAndUpdate(filter, update, options).Seq;
}

答案 1 :(得分:0)

好的,这是我使用反射的丑陋解决方案

public class SeqIntIdGenerator<TEntity> : IIdGenerator
{
    var containerType = container.GetType();
    var database = (IMongoDatabase)containerType.GetProperty("Database").GetValue(container);
    var collectionNamespace = (CollectionNamespace)containerType.GetProperty("CollectionNamespace").GetValue(container);

    var idSequenceCollection = database.GetCollection<dynamic>("Counters");

    var filter = Builders<dynamic>.Filter.Eq("_id", collectionNamespace.CollectionName);
    var update = Builders<dynamic>.Update.Inc("Seq", 1);

    var options = new FindOneAndUpdateOptions<dynamic>
    {
        IsUpsert = true,
        ReturnDocument = ReturnDocument.After
    };

    return idSequenceCollection.FindOneAndUpdate(filter, update, options).Seq;
    }

    public bool IsEmpty(object id)
    {
        return (int)id == 0;
    }
}