LoginSignup
9
10

More than 5 years have passed since last update.

Realm Xamarinで基本的なRealmの扱いメモ

Last updated at Posted at 2016-06-14

前提

やること

Dogモデルから以下のことを行います。

  • 取り出し
  • id指定取り出し
  • 挿入
  • id指定更新
  • 全削除
  • id指定削除

免責事項

私がこれでやりやすいと思っていただけで、これがRealmらしい書き方かは保証できません。
もし、これより正しいやり方をご存知でしたら編集リクエストやコメントでお願いします。

Dogを修正

以前のよりも主キーのSSNが増えてます。
Ownerクラスは使ってないため、Dogから消してもいいかもしれません。

Swift版を知ってる方

Swift版と違い、SwiftではprimaryKey()のオーバーライドだけで主キー設定ができましたが、[ObjectId]のAttributeがついています。

Dog.cs
using System;
using System.Collections.Generic;
using Realms;

namespace 自分のプロジェクト名
{
    // Define your models like regular C# classes
    public class Dog : RealmObject 
    {
        [ObjectId]
        public string SSN { get; set; }

        public string Name { get; set; }
        public int Age { get; set; }
        public Person Owner { get; set; }
    }

    public class Person : RealmObject 
    {
        public string Name { get; set; }
        public RealmList<Dog> Dogs { get; } 
    }
}

コントローラを作成

Screen Shot 2016-06-14 at 8.40.04 AM.png
Dogモデルから操作するクラスをScripts/Controllers/DogController.csに作成した。
今回、Scriptsフォルダを作成し、その中にControllersフォルダを作成しています。

DogController.cs
using Realms;
using System.Diagnostics;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace 自分のプロジェクト名
{
    public class DogController
    {
        private Realm realm;

        public DogController ()
        {
            this.realm = Realm.GetInstance();
        }

        public void Insert(Dog newDog)
        {
            // トランザクションを用いてオブジェクトを保存・更新します.
            this.realm.Write(() =>
            {
                var id = this.Count();  
                var mydog = realm.CreateObject<Dog>();
                mydog.SSN = (id).ToString ();
                mydog.Name = newDog.Name;
                mydog.Age = newDog.Age;
            });
        }

        public void Update(string id, Dog dog)
        {
            if (this.CountById(id) == 0)
            {
                return;
            }

            var res = this.realm.All<Dog>().Where(d => d.SSN == id).Single();
            using(var trans = realm.BeginWrite())
            {
                res.Name = dog.Name;
                res.Age = dog.Age;
                res.Owner = dog.Owner;
                trans.Commit();
            }
        }

        public Dog FindById(string id)
        {
            if (this.CountById(id) == 0)
            {
                return null;
            }

            return this.realm.All<Dog>().Where(d => d.SSN == id).Single();
        }

        public Dog[] FindAll()
        {
            return this.realm.All<Dog>().ToArray();
        }

        public int Count()
        {
            return this.realm.All<Dog>().Count();
        }       

        public int CountById(string id)
        {
            return this.realm.All<Dog>().Where(d => d.SSN == id).Count();
        }

        public void DeleteAll()
        {
            // トランザクションを開始してオブジェクトを削除します.
            using (var trans = this.realm.BeginWrite())
            {
                // これはだめ.
//              foreach (var dog in realm.All<Dog>())
//              {
//                  this.realm.Remove(dog);
//              }
                this.realm.RemoveAll<Dog>();
                trans.Commit();
            }
        }

        public void DeleteById(string id)
        {
            var obj = this.FindById(id);
            if (obj == null)
            {
                return; 
            }

            // Delete an object with a transaction
            using (var trans = this.realm.BeginWrite ()) {
                this.realm.Remove(obj);
                trans.Commit();
            }
        }
    }
}

主キーは自分でインクリメントすることになります。面倒ですが・・。自動でいいのに。

実行するには

まず古いRealm消す。

以前実行した場合、Realmのデータが残っています。
手順はAndroidのエミュレータです。
アプリごと消します。
※もっといい消し方があればコメントお願いします。

Realmファイルを消す手順です

  1. シミュレータのデスクトップのSettingsを選択
    Screen Shot 2016-06-14 at 8.45.32 AM.png

  2. DEVICEの中のAppsを選択
    Screen Shot 2016-06-14 at 8.45.43 AM.png

  3. 該当アプリを選択
    Screen Shot 2016-06-14 at 8.45.46 AM.png

  4. Uninstallで消す。
    Screen Shot 2016-06-14 at 8.45.49 AM.png

注意!・・・この手順は面倒なので、もしもっと楽な方法があると思うので教えて下さい。

このクラスは自由です。
SetDB()メソッドを実行しましょう。
Dump()メソッドは中身を出力するために記載しました。

test.cs

        private void SetDB()
        {
            Debug.WriteLine(new string('*', 10));

            var dc = new DogController ();
            dc.DeleteAll();

            var myDog = new Dog() { Name = "一郎", Age = 10 };
            var myDog2 = new Dog() { Name = "次郎", Age = 11 };
            var myDog3 = new Dog() { Name = "三郎", Age = 12 };
            dc.Insert(myDog);
            dc.Insert(myDog2);
            dc.Insert(myDog3);

            Debug.WriteLine(new string('*', 10));

            Debug.WriteLine("count:{0}", dc.Count());
            var dogs = dc.FindAll();
            this.Dump(dogs);

            dc.DeleteById("1");
            dc.DeleteById("1");

            dogs = dc.FindAll();
            this.Dump(dogs);

            var newDog = new Dog() { Name = "ネオドッグ", Age = 22 };
            dc.Update("5", newDog);
            dogs = dc.FindAll();
            this.Dump(dogs);
        }

        private void Dump(Dog[] dogs)
        {
            // ダンプする.
            foreach (var dog in dogs)
            {
                Debug.WriteLine("id:{0}, name:{1}, age:{2}",
                    dog.SSN, dog.Name, dog.Age);
                Debug.WriteLine(new string('-', 10));
            }
        }
    }

実行した時の効果。

  • 一郎、次郎、三郎の犬を3匹追加。
  • カウントも出してます。
  • 主キーidDogConrtrollerのおかげで自動でインクリメントされます。
  • id1を指定して、2回消しています。これはあえて実験のため。エラーにならないように対処してます。
  • id5に対して更新しています。しかし5はいないので何も起こりません。id2の次郎や3の三郎に対して行えば、ネオドッグに変化するはずです。

次回

今回Dog限定でその都度クラスが必要なので、Genericsクラスで汎用的にできるものを作成予定です。

9
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
10