繁体   English   中英

带有C#驱动程序2.0的MongoDB被冻结

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM