MongoDB Realmを利用したCRUD機能を実装しよう

2022年8月4日(木)
柴田 凌輔由井 秀弥三又 優人

はじめに

前回は、MongoDB RealmのCustom User Dataという機能を使用してアプリの管理者ユーザーを追加しました。

今回は、MongoDB Realmを使用してCRUD機能を作成していきます。CRUD機能を作成することにより、アプリ上で商品情報を管理できるようになります。

本稿で使用するサンプルコードは、こちらからダウンロードできます。

モデルの作成

まずは、商品情報をMongoDB Realmで管理するために必要なモデルをC#コードで作成していきます。今回は以下6つの情報を定義して使用します。

  • ID
  • Partition
  • 商品名
  • 定価
  • 割引率
  • 最終更新日時

第3回にも記述しましたが、Realmアプリと接続する場合はIDとPartitionを定義しておく必要があります。よって、それ以降が商品情報の本体部分となります。

商品名を“Item”、定価を“Price”、割引率を“DiscountRate”、最終更新日時を“Timestamp”プロパティに定義します。

[MapTo("item")]
[Required]
public string Item { get; set; }

[MapTo("price")]
public int Price { get; set; }

[MapTo("discount_rate")]
public int DiscountRate { get; set; }

[MapTo("timestamp")]
public DateTimeOffset Timestamp { get; set; }

【参照】https://gitlab.com/creationline/mongodb-realm-mobileapp/-/blob/Chapter8/SampleApp/Models.cs

画面構成と遷移

CRUD機能を実装するために作成する画面は、以下の3つです。サインイン機能を作成したときと同様に、Fragmentを作成して制御します。

  • トップ画面
  • 商品追加画面
  • 商品編集画面

トップ画面は、第6回で作成したサインイン後の画面です。トップ画面では、以前作成したサインアウト機能に加え、商品一覧を表示します。また、商品項目をクリックすることで商品編集画面に、商品追加ボタンをクリックすることで商品追加画面にそれぞれ遷移できます。

商品追加画面では新規に商品情報を追加を行います。入力フォームに商品名と定価、割引率を入力し、追加ボタンをクリックすることで商品情報が追加されます。商品の追加後や戻るボタンをクリックした際は、トップ画面に遷移するように構成されています。

商品編集画面では商品情報の編集と削除をします。入力フォームに変更したい内容を入力し、更新ボタンをクリックすることで商品情報が更新されます。更新後は商品追加画面と同様にトップ画面に遷移します。また、削除ボタンをクリックすると商品情報が削除され、トップ画面に遷移します。

サンプルコードの説明

読み込み機能

・トップ画面レイアウト

トップ画面のレイアウトはResources/layout配下にあるtop.xmlファイルで定義されています。

【参照】https://gitlab.com/creationline/mongodb-realm-mobileapp/-/blob/Chapter8/SampleApp/Resources/layout/top.xml

・トップフラグメント

プロジェクト直下にあるTopFragment.csは商品一覧を表示するためのコードです。

【参照】https://gitlab.com/creationline/mongodb-realm-mobileapp/-/blob/Chapter8/SampleApp/TopFragment.cs

・商品一覧の表示

はじめに、Realmのインスタンス作成と同期設定を行います。

using Realm publicRealm = Realm.GetInstance(
       new SyncConfiguration(((MainActivity)this.Activity).PUBLIC_PARTITION, app.CurrentUser, 
               Path.Combine(((MainActivity)this.Activity).realmDir, "public.realm")));

次に、ローカルのRealmデータベースにある商品一覧をAll関数で取得します。ここでは、OrderByDescending関数を合わせて使用することでTimestampを基準とした降順で呼び出しています。

var list = publicRealm.All<Inventory>().OrderByDescending(i => i.Timestamp).ToList();

・商品項目のクリックイベント

OnListItemClick関数では、商品一覧を取得後に遷移先で必要なId、Item、Price、DiscountRateを、クリックした商品項目の位置をもとにリストから取り出し、Bundleを通して遷移先のEditFragmentに渡しています。

public void OnListItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
    …
    var list = publicRealm.All<Inventory>().OrderByDescending(i => i.Timestamp).ToList();
    EditFragment ef = new EditFragment();
    Bundle bundle = new Bundle();
    bundle.PutString("mongo_id", $"{list[e.Position].Id}");
    bundle.PutString("item", $"{list[e.Position].Item}");
    bundle.PutString("price", $"{list[e.Position].Price}");
    bundle.PutString("discount_rate", $"{list[e.Position].DiscountRate}");
    ef.Arguments = bundle;
    Utils.ChangeFragment(this.ParentFragmentManager, ef);
}

追加機能

・追加画面のレイアウト

追加画面のレイアウトはResources/layout配下にあるadd.xmlファイルで定義されています。

【参照】https://gitlab.com/creationline/mongodb-realm-mobileapp/-/blob/Chapter8/SampleApp/Resources/layout/add.xml

・追加フラグメント

プロジェクト直下にあるAddFragment.csは商品情報を新規で追加するためのコードです。

【参照】https://gitlab.com/creationline/mongodb-realm-mobileapp/-/blob/Chapter8/SampleApp/AddFragment.cs

・追加ボタンのクリックイベント

AddInventory関数ではローカルのRealmデータベースにドキュメントを追加しています。正常にドキュメントを追加できた場合はTopFragmentに遷移します。追加できなかった場合はエラーを示すポップアップを表示させます(ShowPopup関数はUtils.csで記載されています。また、バリデーションチェックコードなどもここに記載されておりますので、興味のある方はそちらを参照してください)。

 try
 {
   …
    // 商品情報を追加する
    publicRealm.Write(() =>
         publicRealm.Add(new Inventory()
         {
            Item = itemText.Text,
            Partition = ((MainActivity)this.Activity).PUBLIC_PARTITION,
            Price = price,
            DiscountRate = discount,
           }));
}
catch
{
    Utils.ShowPopup(this.Activity, "商品の追加に失敗しました", (sender, e) => { });
    ((Button)sender).Enabled = true;
    return;
 }

Utils.ShowPopup(this.Activity, "商品が追加できました", (sender, e) =>                
        Utils.ChangeFragment(this.ParentFragmentManager, new TopFragment()));

第2回の復習になりますが、RealmデータベースをC#で操作する際にはWrite(トランザクション)内にAddメソッドなどのデータベース操作アクションを挿入します。

クリエーションライン株式会社 Exploratory Development & Incubation Team
22年度卒の新卒エンジニア。大学時代の先輩に憧れ、アジャイルの精神を持ったクラウドネイティブエンジニアになるために日々勉強中。趣味は珈琲を淹れること。不定期に会社内の懇親会で披露することも。
クリエーションライン株式会社 Exploratory Development & Incubation Team
22年度卒の新卒エンジニア。学生時代は災害援助ロボットの研究をする傍ら、2020年9月からアルバイトとしてIoT教材の作成に従事。最近はAzureの資格をとるために奮闘中。趣味はドライブで、温泉巡りをしています。
クリエーションライン株式会社 Exploratory Development & Incubation Team
22年度卒の新卒エンジニア。大学は経済学部だが、新しいものが好きで、これからの時代を切り開いていくITの世界に興味を持った。未経験からC#やLinuxなどの技術的な研修を経て、エンジニアとしての一歩を踏み出した。趣味はポーカーで最近の夢はWorld Series of Pokerに出場すること。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています