使用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;
}
Run Code Online (Sandbox Code Playgroud)
如果您希望快速使用上述代码,可以使用以下代码进行演示(初始加载):
AuctionCache ac = new AuctionCache();
ac.lastModified = (double)12345679;
ac.server = "Foo";
// should return true on subsequent loads.
Console.WriteLine( IsCached( ac ) );
Run Code Online (Sandbox Code Playgroud)
确保在初始创建后测试停止程序,然后使用以下代码启动程序"fresh"以进行加载/更新数据库的干净测试:
AuctionCache ac = new AuctionCache();
ac.lastModified = (double)22345679;
ac.server = "Foo";
// should return true on subsequent loads.
Console.WriteLine( IsCached( ac ) );
Run Code Online (Sandbox Code Playgroud)
这将确保它会尝试更新记录并标记问题在你的IDE为lastModified比存储在一个新的cache.db,这将触发.Update我的内部方法IsCached的方法.
mbd*_*vid 14
如果您有一个没有标识的对象,LiteDB会将您的对象转换为BsonDocument并在插入时创建一个新的"_id".如果您查询数据库(使用shell),您可以使用_id(ObjectId)查看您的文档.
但是,要更新文档,必须使用插入时生成的_id(请参阅此处:https://github.com/mbdavid/LiteDB/blob/v2.0.0-rc/LiteDB/Core/Collections/Update.cs#L25).只有将此_id存储在另一个数据库(sql)中或仅用于插入时,没有id的文档才有用.
在您的示例中,如果server您是文档ID,请使用[BsonId]属性来解决或创建public Guid Id { get; set; }