簡體   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