概要
- LiteDBでは DbRef/BsonRef + Include() で リレーションを定義/解決できます
- ただし、コレクションにオブジェクトを追加する際、参照先の項目が先にコレクションに存在しない場合、参照元(
DbRefや[BsonRef]を指定した側)を更新した際に参照情報が失われます - 参照先、子側のコレクションを先に更新しよう
コードで解説
クラスとコレクションの定義がこうだとして
// 参照元クラス
public sealed class StoryboardFrameEntity
{
public Guid FrameId { get; set; }
[BsonRef]
public List<StoryboardDialog> Dialogs { get; set; } = new();
}
// 参照先クラス
public sealed class StoryboardDialog
{
[BsonId(autoId:true)]
public int DialogId { get; set; }
public string DialogText { get; set; } = "";
}
private readonly ILiteCollection<StoryboardFrameEntity> _frameCollection;
private readonly ILiteCollection<StoryboardDialog> _dialogsCollection;
_frameCollection = _liteDatabase.GetCollection<StoryboardFrameEntity>();
_dialogsCollection = _liteDatabase.GetCollection<StoryboardDialog>();
OKパターン
// 先に参照先アイテムをコレクションに追加している
// こうすれば_frameCollection.Upsert() 時にentity.Dialogsを参照として解決できると思われる
_dialogsCollection.Upsert(entity.Dialogs);
_frameCollection.Upsert(entity);
NGパターン
// 参照先アイテムがコレクションに無い状態で更新している
_frameCollection.Upsert(entity);
_dialogsCollection.Upsert(entity.Dialogs);
// var otherEntity = _frameCollection.Include(x => x.Dialogs).FindById(entity.FrameId);
// 再取得した otherEntity の Dialogs は 更新前の状態のままになっているはず
参考