MongoDb C# class 层次结构的顺序 int id 生成器
MongoDb sequential int id generator for C# class hierarchy
我有一个带有独立 BsonClass 映射的 C# classes 层次结构。我所有的 classes 都使用自定义顺序 int id 生成。最后一个 ID 存储在名为 "Counter" 的特殊集合中。我的问题是当 mongo 收集方法(如 InsertOneAsync 调用 InvalidCastException)被抛出时。
基础实体class:
[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));
}
}
Child class:
public class Child : Entity<int>
{
public int SomeData { get; set; }
}
基地class地图:
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));
});
}
}
Child class 地图:
public class ChildMap
{
public static void Register()
{
BsonClassMap.RegisterClassMap<Child>(cm =>
{
cm.AutoMap();
cm.SetIgnoreExtraElements(true);
});
}
}
顺序 int id 生成器 class:
public class SeqIntIdGenerator<TEntity> : IIdGenerator
{
public static SeqIntIdGenerator<TEntity> Instance { get; } = new SeqIntIdGenerator<TEntity>();
public object GenerateId(object container, object document)
{
//InvalidCastException thrown here on InsertOneAsync!!!
var idSequenceCollection = ((IMongoCollection<TEntity>)container).Database.GetCollection<dynamic>("Counters");
var filter = Builders<dynamic>.Filter.Eq("_id", ((IMongoCollection<TEntity>)container).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;
}
}
将容器从 Object 转换为 IMongoCollection> 时抛出 InvalidCastException。怎么做才对?我的C#驱动版本是2.7.2.
好的,这是我使用反射的丑陋解决方案
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;
}
}
如果你已经在使用动态,你可以关掉那个的反射代码>
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;
}
我有一个带有独立 BsonClass 映射的 C# classes 层次结构。我所有的 classes 都使用自定义顺序 int id 生成。最后一个 ID 存储在名为 "Counter" 的特殊集合中。我的问题是当 mongo 收集方法(如 InsertOneAsync 调用 InvalidCastException)被抛出时。
基础实体class:
[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));
}
}
Child class:
public class Child : Entity<int>
{
public int SomeData { get; set; }
}
基地class地图:
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));
});
}
}
Child class 地图:
public class ChildMap
{
public static void Register()
{
BsonClassMap.RegisterClassMap<Child>(cm =>
{
cm.AutoMap();
cm.SetIgnoreExtraElements(true);
});
}
}
顺序 int id 生成器 class:
public class SeqIntIdGenerator<TEntity> : IIdGenerator
{
public static SeqIntIdGenerator<TEntity> Instance { get; } = new SeqIntIdGenerator<TEntity>();
public object GenerateId(object container, object document)
{
//InvalidCastException thrown here on InsertOneAsync!!!
var idSequenceCollection = ((IMongoCollection<TEntity>)container).Database.GetCollection<dynamic>("Counters");
var filter = Builders<dynamic>.Filter.Eq("_id", ((IMongoCollection<TEntity>)container).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;
}
}
将容器从 Object 转换为 IMongoCollection> 时抛出 InvalidCastException。怎么做才对?我的C#驱动版本是2.7.2.
好的,这是我使用反射的丑陋解决方案
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;
}
}
如果你已经在使用动态,你可以关掉那个的反射代码>
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;
}