SQLite-Net Extension both one-to-one and one-to-many relationships between two entities

papafe picture papafe · Mar 12, 2015 · Viewed 8.3k times · Source

I am using SQLite-Net PCL together with SQLite-Net extensions for the development of an application using Xamarin.

In my model I have two entities, let us call them A and B, that are connected by both a one-to-one and a one-to-many relationships. For instance, A has a one-to-one relationship with B, and A has also a one-to-many relationship with B.

Is it possible to express such behaviour with SQLite-Net extensions?

Answer

redent84 picture redent84 · Mar 12, 2015

Yes, but you have to explicitly declare the foreign keys and inverse properties in the relationship attribute, because otherwise the library may get the wrong foreign key for the relationship.

    public class ClassA
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }

        [OneToMany("O2MClassAKey", "BObjectsInverse")]
        public List<ClassB> BObjects { get; set; }

        [OneToOne("O2OClassAKey", "BObjectInverse")]
        public ClassB BObject { get; set; }

        // Other properties
        public string Bar { get; set; }
    }
        
    public class ClassB
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }

        [ForeignKey(typeof (ClassA))]
        public int O2MClassAKey { get; set; }

        [ForeignKey(typeof (ClassA))]
        public int O2OClassAKey { get; set; }

        // Inverse relationships, these are optional
        [ManyToOne("O2MClassAKey", "BObjects")]
        public ClassA BObjectsInverse { get; set; }
        [OneToOne("O2OClassAKey", "BObject")]
        public ClassA BObjectInverse { get; set; }

        // Other properties
        public string Foo { get; set; }
    }

Please note that the foreign key O2OClassAKey for the OneToOne relationship can be declared in any of the classes.

If you don't need inverse properties, you can skip them in the relationship attribute:

    public class ClassA
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }

        [OneToMany("O2MClassAKey")]
        public List<ClassB> BObjects { get; set; }

        [OneToOne("O2OClassAKey")]
        public ClassB BObject { get; set; }

        // Other properties
        public string Bar { get; set; }
    }
        
    public class ClassB
    {
        [PrimaryKey, AutoIncrement]
        public int Id { get; set; }

        [ForeignKey(typeof (ClassA))]
        public int O2MClassAKey { get; set; }

        [ForeignKey(typeof (ClassA))]
        public int O2OClassAKey { get; set; }

        // Other properties
        public string Foo { get; set; }
    }