LiteDB: недопустимый тип данных BSON 'Null' в поле '_id'

С помощьюLiteDBи это удивительно. Он хорошо работает для загрузки и хранения данных, но не для последующих загрузок после создания базы данных.

При начальной загрузке все идеально. Он создает базу данных и сохраняет новую запись без ошибок, а запрос возвращает пустой, так как в этой коллекции еще ничего не существует.

При последующей загрузке, после запроса данных (работает и получает результат), возникает проблема в.Update() которая вызывает эту проблему. Согласно их документации, когда «Id» не указан, он должен быть создан. Когда объект возвращается из коллекции, он не содержит это поле _Id и, следовательно, не может обновить запись в базе данных.

public class AuctionCache
{
    public double lastModified { get; set; }
    public string server { get; set; }
    public AuctionCache() { }
}

private static bool IsCached(AuctionCache auction)
{
    string filename = string.Format("{0}-{1}.json", auction.server, auction.lastModified);
    bool cached = false;
    try
    {
        using (LiteDatabase db = new LiteDatabase("cache.db"))
        {
            // Get customer collection
            var auctions = db.GetCollection<AuctionCache>("auctions");

            // Use Linq to query documents
            try
            {
                var results = auctions.Find(x => x.server == auction.server).DefaultIfEmpty(null).Single();
                if (results == null)
                {
                    // Insert new cached server
                    auctions.Insert(auction);
                    auctions.EnsureIndex(x => x.server);
                }
                else
                {
                    if (results.lastModified < auction.lastModified)
                    {
                        // Update existing cached server data
                        results.lastModified = auction.lastModified;
                        auctions.Update(results);
                        auctions.EnsureIndex(x => x.server);
                    }
                    else
                    {
                        cached = File.Exists(filename);
                    }
                }
            }
            catch (LiteException le1) {
                Log.Output(le1.Message);
                // Get stack trace for the exception with source file information
                var st = new StackTrace(le1, true);
                // Get the top stack frame
                var frame = st.GetFrame(0);
                // Get the line number from the stack frame
                var line = frame.GetFileLineNumber();
                var module = frame.GetMethod();
                var file = frame.GetFileName();
            }
            catch (Exception e)
            {
                Log.Output(e.Message);
                // Get stack trace for the exception with source file information
                var st = new StackTrace(e, true);
                // Get the top stack frame
                var frame = st.GetFrame(0);
                // Get the line number from the stack frame
                var line = frame.GetFileLineNumber();
            }
        }
    } catch (Exception ee) {
        Log.Output(ee.Message);
        // Get stack trace for the exception with source file information
        var st = new StackTrace(ee, true);
        // Get the top stack frame
        var frame = st.GetFrame(0);
        // Get the line number from the stack frame
        var line = frame.GetFileLineNumber();
    }
    return cached;
}

Если вы хотите использовать приведенный выше код быстро, вы можете использовать следующее для демонстрационных целей (начальная загрузка):

   AuctionCache ac = new AuctionCache();
   ac.lastModified = (double)12345679;
   ac.server = "Foo";

   // should return true on subsequent loads.
   Console.WriteLine( IsCached( ac ) );

Убедитесь, что при тестировании, чтобы остановить программу после первоначального создания, а затем запустите программу «заново» для чистого теста загрузки / обновления базы данных, используя следующий код:

   AuctionCache ac = new AuctionCache();
   ac.lastModified = (double)22345679;
   ac.server = "Foo";

   // should return true on subsequent loads.
   Console.WriteLine( IsCached( ac ) );

Это должно гарантировать, что он попытается обновить запись и пометить проблему в вашей IDE какlastModified новее, чем хранится вcache.db который вызовет.Update метод внутри моегоIsCached метод.

Ответы на вопрос(1)

Ваш ответ на вопрос