[英]MongoDB with C# driver 2.0 is frozen
我正在使用MongoDB 2.0驱动程序运行C#应用程序,并且在运行所有测试时遇到以下错误:
System.InvalidOperationException : Class map for <TopClassName> has been frozen and no further changes are allowed.
System.AggregateException : One or more errors occurred. ----> MongoDB.Bson.BsonException : Unable to find a matching member to provide the value for parameter 'inBed'
但是,一次运行每个测试不会产生任何错误。 所以由于某种原因,班级地图被冻结了...
这是我所拥有的(PS,如果您发现有问题的地方,请告诉我):
具有3个抽象类和一个具体类的层次结构:
public abstract class BaseEvent
{
[BsonId]
public Guid Id;
public List<int> Data;
public dynamic Condition;
public string TimeStamp;
[BsonConstructor]
protected BaseEvent(List<int> data, dynamic condition)
{
Data = data;
Condition = condition;
TimeStamp = DateTime.Now.ToString();
Id = Guid.NewGuid();
}
}
public abstract class Basic : BaseEvent
{
[BsonConstructor]
protected Basic(List<int> data, bool condition) : base(data, condition)
{}
}
public abstract class BedEvent : Basic
{
[BsonConstructor]
protected BedEvent(List<int> data, bool inBed) : base(data, inBed)
{}
}
public class DummyBed : BedEvent
{
[BsonConstructor]
public DummyBed(List<int> data, bool inBed) : base(data, inBed)
{
RegisterHelper.RegisterNewClass(this);
}
}
RegisterHelper
是一个保持活动状态的单例,更多的则是向下移动。 我的应用程序的构造函数将注册顶级类BaseEvent
:
var baseEvent = BsonClassMap.RegisterClassMap<BaseEvent>(cm =>
{
cm.SetIsRootClass(true);
cm.MapMember(c => c.Data);
cm.MapMember(c => c.Condition);
cm.MapMember(c => c.TimeStamp);
cm.MapIdMember(c => c.Id).SetIdGenerator(GuidGenerator.Instance);
});
RegisterHelper.ClassRegister.Add(baseEvent);
对于每个具体的类,如DummyBed
,我都调用一个自制的(很可能是造成问题的原因)注册方法。
此方法查看所有基类,如果未在列表中找到,则将它们递归地添加到它们自身之上的所有类,如下所示:
public static void RegisterNewClass<T>(T theObject)
{
...
if (!lvl3Found)
{
var lvl3Map = new BsonClassMap(lvl3Type); //lvl3Type is a System.Type
lvl3Map.SetDiscriminator(lvl3Type.Name);
ClassRegister.Add(lvl3Map);
BsonClassMap.RegisterClassMap(lvl3Map);
lvl4Map.AddKnownType(lvl3Type);
}
...
}
完整的课程可以在这里找到 。
运行测试:
[TestFixture]
public class InsertEventIntoDatabaseTest
{
private EventDatabase _eventDatabase;
[SetUp]
public void Setup()
{
_eventDatabase = new EventDatabase();
_eventDatabase.EmptyDatabase(); //Clean slate each time
}
[TearDown]
public void TearDown()
{
_eventDatabase = null;
}
[Test]
public void GetSubTypeDocument_FindDummyBed_Success()
{
var bed = new DummyBed(new List<int>() { 1, 2, 3}, true);
_eventDatabase.InsertEventInDatabase(bed);
var doc = _eventDatabase.GetDocument();
_eventDatabase.GetSubTypeDocument(typeof(DummyBed));
Assert.That(doc, Is.TypeOf<DummyBed>()); //Great success
}
[Test]
public void FindTypeEvents_FindTwo_Succes()
{
var data = new List<int>() { 1, 2, 3 };
var bed1 = new DummyBed(data, true);
var bed2 = new DummyBed(data, true);
_eventDatabase.InsertEventInDatabase(bed1);
_eventDatabase.InsertEventInDatabase(bed2);
var foundEvents = _eventDatabase.FindTypeEvents(typeof(BedEvent));
Assert.That(foundEvents.Count, Is.EqualTo(2)); // Frozen
}
...
}
但是,自行运行每个测试只会给出绿色的复选标记。 因此,取决于事件处理的速度。
每次运行新测试时都会清除数据库,因此不应运行任何操作。
调用的方法应等待它们完成:
public void InsertEventInDatabase(BaseEvent inputBaseEvent)
{
inputBaseEvent.Condition = (inputBaseEvent.Condition is bool ? (inputBaseEvent.Condition == true ? 100 : 0) : inputBaseEvent.Condition);
var collection = _database.GetCollection<dynamic>(DatabaseCollection);
collection.InsertOneAsync(inputBaseEvent).Wait(); //Should wait, right?
}
public List<BaseEvent> FindTypeEvents(Type typeFilter)
{
var name = _database.GetCollection<BaseEvent>(DatabaseCollection)
.Find(x => x.Id != Guid.Empty)
.ToListAsync();
return name.Result; //Should wait here as well, right?
}
关于在哪里寻找问题原因的任何建议? C#驱动程序的四月更新后,互连网上的信息非常有限,因此欢迎提出任何建议。
因此,该错误并没有消失,但是如果被忽略,显然并不会影响系统。
我相信这是一个错误,但是我现在有34个绿色单元测试,并且系统在发布模式下运行良好。
public static void RegisterNewClass<T>(T theObject)
{
...
if (!lvl3Found)
{
try
{
lvl3Map.SetDiscriminator(lvl3Type.Name);
BsonClassMap.RegisterClassMap(lvl3Map);
lvl4Map.AddKnownType(lvl3Type);
}
catch (Exception e)
{
Console.WriteLine("Level 3 adding went wrong!");
Console.WriteLine(e.Message);
}
}
...
}
我不能说为什么它真正起作用。 触发该异常的原因是行lvl4Map.AddKnownType(lvl3Type)
说明lvl4Map
已冻结。 但是如前所述,测试仍然运行时带有绿色标记,因此我不确定这没什么大不了的。 这可能是一个错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.