2016-07-13 2 views
3

LiteDB을 사용하면 매우 놀랍습니다. 그러나 데이터를로드하고 저장하는 데는 잘 작동하지만 데이터베이스를 만든 후 후속로드에는 적합하지 않습니다.LiteDB : 유효하지 않은 BSON 데이터 유형 '_id'필드에 'Null'

초기로드시 모든 것이 완벽합니다. 데이터베이스를 생성하고 새로운 레코드를 완벽하게 저장하며 쿼리는 아직 그 콜렉션에 아무것도 없으므로 빈을 반환합니다.

데이터를 쿼리 한 후 작동하여 결과를 얻은 후 계속로드하면이 문제의 원인이되는 .Update()에 문제가 있습니다. 그들의 문서에 따르면, 'Id'가 지정되지 않았 으면 '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)); 

: 다음 코드를 사용하여 데이터베이스를 업데이트 /로드 깨끗한 시험 '신선한'프로그램을 시작 IDE의 문제가 지연되어 lastModified이 내 IsCached 메서드 내에서 .Update 메서드를 트리거하는 cache.db에 저장된 것보다 최신 인 경우

답변

6

식별이없는 개체가있을 때 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?"이 무슨 뜻이야? ? –

관련 문제