1

コンテキスト: を使用SQLite-Net Extensionsしてローカル データ キャッシングを行っていXamarinます。iOS、Android、Windows Phone への展開を予定しています。この方法で保存したいシステム全体で使用される既存のデータ構造 (すべて共通のインターフェースを実装) があります。

問題 コード サンプルに示されているように、[ManyToOne]属性は関係フィールドを示すために使用されます。これは動作しません。BitBucket 開発者ページで説明されているように、[ForeignKey]属性を使用して外部キー関係を指定できます。これは一見、int. Id フィールドのプロパティを複製することなく、これらの関係をサポートするように構造を簡単に適応させることができますか? 例えば、以下は望ましくありません。

    [ForeignKey(typeof(Address))]
    public int AddressId { set; get; }

    [ManyToOne]
    public Address Address
    {
        set { address = value; }
        get { return address; }
    }

コードサンプル

using SQLite.Net.Attributes;
using SQLiteNetExtensions.Attributes;

namespace Data
{
    [Table("Client")]
    public class Client : IData
    {
        private int id = -1;
        private Address address = null;

        public Client() { }

        public Client(int id)
        {
            this.id = id;
        }

        [PrimaryKey, AutoIncrement, Column("_id")]
        public int Id
        {
            set { id = value; }
            get { return id; }
        }

        [ManyToOne]
        public Address Address
        {
            set { address = value; }
            get { return address; }
        }
    }

    [Table("Address")]
    public class Address : IIdentifiable
    {
        private int id = -1;
        private string someFields = "";

        public Address() { }

        public Address(int id)
        {
            this.id = id;
        }

        [PrimaryKey, AutoIncrement, Column("_id")]
        public int Id
        {
            set { id = value; }
            get { return id; }
        }

        public string SomeFields
        {
            set { someFields = value; }
            get { return someFields; }
        }
    }
}
4

1 に答える 1

1

SQLite-Net 拡張機能は、SQLite-Net 上の薄いレイヤーであり、ストレージに sqlite データベースを使用します。リレーショナル データベースは外部キーを使用してリレーションを格納しますが、この点では sqlite も例外ではありません。したがって、SQLite-Net および SQLite-Net 拡張機能も、関係を宣言するために外部キー メカニズムを使用します。

別の方法として、中間テーブルを使用して関係を格納することもできます。これは、関係がManyToMany機能するのと同じ方法ですが、端の 1 つを 1 つに制限します。このようにして、 ManyToMany リレーションシップと中間テーブルを使用してOneToManyManyToOneまたはリレーションシップを模倣します。OneToOne例えば:

[Table("Client")]
public class Client {

    [PrimaryKey, AutoIncrement, Column("_id")]
    public int Id { get; set; }

    [Ignore] // This property shouldn't be persisted
    public Address Address { get; set; }

    // This relationship is in fact a ManyToOne relationship,
    // but we model it as a ManyToMany to avoid adding foreign key to this entity
    [ManyToMany(typeof(AddressesClients))]
    public Address[] Addresses { 
        get { return Address != null ? new []{ Address } : Address; } 
        set { Address = value.FirstOrDefault(); }
    }
}

[Table("Address")]
public class Address
{
    [PrimaryKey, AutoIncrement, Column("_id")]
    public int Id { get; set; }

    public string SomeFields { get; set; }

    [ManyToMany(typeof(AddressesClients), ReadOnly = true)]
    public List<Client> Clients { get; set; }
}

// Intermediate table that defines the relationship between Address and Client
class AddressesClients {
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }

    [ForeignKey(typeof(Client))]
    public int ClientId { get; set; }

    [ForeignKey(typeof(Address))]
    public int AddressId { get; set; }
}

もちろん、これにはいくつかのパフォーマンス上のペナルティがあります。

についてはPrimaryKey、サポートされている任意の型を使用できます。反対の にもまったく同じ型を使用する必要があります。ForeignKeyつまり、主キーとして使用する場合、そのクラスを指すGuid外部キーも である必要があります。デモ プロジェクトでは、既に(最もパフォーマンスの高い)を使用しており、.GuidintstringUUID

于 2015-10-21T15:44:22.207 に答える