2016-07-13 6 views
3

LiteDBを使用すると素晴らしいです。ただし、データのロードおよび格納には効果的ですが、データベースの作成後の後続のロードでは機能しません。LiteDB: '_id'フィールドに無効なBSONデータ型 'Null'があります。

初期ロード時にはすべてが完璧です。データベースを作成して新しいレコードを完璧に保存し、そのコレクションには何もまだ存在しないため、クエリは空を返します。

データを照会した後に結果が得られた後で、この問題の原因となっている.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)); 

初期作成後にプログラムを停止するためにテストするときに確認して、これは、それがレコードとFを更新しようとしていることを確認する必要があります

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

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

:次のコードを使用してデータベースを更新/ロードのクリーンなテストのために「新鮮な」プログラムを開始lastModifiedは、に格納されているものよりも新しいので、IsCachedメソッドの中で.UpdateメソッドをトリガーするIDEの問題に遅れが生じます。

答えて

6

IDを持たないオブジェクトがある場合、LiteDBはオブジェクトをBsonDocumentに変換し、挿入時に新しい "_id"を作成します。あなたのデータベース(シェルを使用して)を照会すると、_id(ObjectId)でそこにあなたの文書を見ることができます。

しかし、文書を更新するには、挿入時に生成された_idを使用する必要があります(ここではhttps://github.com/mbdavid/LiteDB/blob/v2.0.0-rc/LiteDB/Core/Collections/Update.cs#L25を参照)。 idを持たない文書は、この_idを別のデータベース(sql)に格納する場合、または挿入する場合にのみ有効です。あなたの例では

serverはあなたがIDを文書であ​​れば、働いていたプロパティを追加public Guid Id { get; set; }

+0

を解決したり、作成する[BsonId]属性を使用します。 :) –

+0

@SamuelJackson L。?? – Kon

+0

@Kon - 1文字の質問が分かりません。あなたは "L?"とは何を意味しますか? ? –

関連する問題