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
метод.