LiteDB: tipo de datos BSON no válido ‘Null’ en el campo ‘_id’

Usando LiteDB , y es increíble. Funciona bien para cargar y almacenar datos, sin embargo, no en cargas posteriores después de que se haya creado la base de datos.

En carga inicial, todo es perfecto. Crea la base de datos y almacena el nuevo registro sin fallas, y la consulta se vuelve vacía ya que no existe nada en esa colección todavía.

En la carga posterior, después de consultar los datos (funciona y obtiene el resultado), hay un problema en el .Update() que está causando este problema. Según su documentación, cuando no se especifica un ‘Id’ se supone que se crea uno. Cuando el objeto se devuelve de la colección, no contiene este campo ‘_Id’ y, por lo tanto, no actualiza el registro en la base de datos.

 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("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  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; } 

Si desea usar el código anterior rápidamente, puede usar lo siguiente para fines de demostración (carga inicial):

  AuctionCache ac = new AuctionCache(); ac.lastModified = (double)12345679; ac.server = "Foo"; // should return true on subsequent loads. Console.WriteLine( IsCached( ac ) ); 

Asegúrese de que al probar para detener el progtwig después de la creación inicial, y luego inicie el progtwig ‘nuevo’ para realizar una prueba limpia de carga / actualización de la base de datos utilizando el siguiente código:

  AuctionCache ac = new AuctionCache(); ac.lastModified = (double)22345679; ac.server = "Foo"; // should return true on subsequent loads. Console.WriteLine( IsCached( ac ) ); 

Esto debería asegurar que intentará actualizar el registro y marcar el problema en su IDE ya que lastModified es más nuevo que el que está almacenado en cache.db lo que activará el método .Update dentro de mi método IsCached .

Cuando tiene un objeto sin identificación, LiteDB convierte su objeto a BsonDocument y crea un nuevo “_id” en la inserción. Si consulta su base de datos (usando shell) puede ver su documento allí con un _id (ObjectId).

Pero, para actualizar su documento, debe usar este _id generado en la inserción (consulte aquí: https://github.com/mbdavid/LiteDB/blob/v2.0.0-rc/LiteDB/Core/Collections/Update.cs#L25 ). Los documentos sin identificación son útiles solo cuando almacena este _id en otra base de datos (sql) o solo para insertar.

En su ejemplo, si el server es su identificación de documento, use el atributo [BsonId] para resolver o crear una public Guid Id { get; set; } public Guid Id { get; set; }