0

I have a problem with SQLite-Net I have three classes: ClassA, ClassB, ClassC. ClassA has OneToMany relation with ClassB. ClassB has ManyToOne Relation with ClassC.

This is my code

using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using SQLite.Net.Attributes;
using SQLiteNetExtensions.Attributes;
using WardFlex.Core.DAL.Interfaces;

    public class ClassA : IEntity
    {
        [XmlAttribute("Id")]
        [PrimaryKey, AutoIncrement]
        public Int64 Id { get; set; }

        public string Kaka { get; set; }

        [OneToMany(CascadeOperations = CascadeOperation.All)]
        public  List<ClassB> ClassBs { get; set; }
    }


    public class ClassB : IEntity
    {
        [XmlAttribute("Id")]
        [PrimaryKey, AutoIncrement]
        public Int64 Id { get; set; }

        [ForeignKey(typeof(ClassA))]
        public Int64 ClassAId { get; set; }

        [ManyToOne]
        public  ClassA ClassA { get; set; }

        [ForeignKey(typeof(ClassC))]
        public Int64 ClassCId { get; set; }

        [ManyToOne]
        public ClassC ClassC { get; set; }
    }        

public class ClassC : IEntity
{
    [XmlAttribute("Id")]
    [PrimaryKey, AutoIncrement]
    public Int64 Id { get; set; }

    [OneToMany(CascadeOperations = CascadeOperation.All)]
    public List<ClassB> ClassBs { get; set; }
}

I Save ClassA entity, but When I try GetAllWithChildren From ClassARepository I can't to see classC entity from ClassB(image was attached) enter image description here

What could be the problem??

Thank you in advance

Konamiman
  • 49,681
  • 17
  • 108
  • 138
Larisa
  • 1
  • 2
  • 1
    Mapping seems OK to me, are you sure that you use InsertWithChildren on save because if not it might be a case where you don't save all the data in first place. There are tools to open sqlite database that work fine so I'd advice to check there if you haven't done so already (personally I use a firefox extension). In our project all these cascade operations were not performing very well so at the end we ended up doing a lot of the stuff that usually the ORM does manually. And we stopped using WithChildren. – kirotab Oct 23 '15 at 14:15
  • 1
    Also check if you're using WithChildren version of the get method when you're getting the data, otherwise you'll have only the key value (not getting the reference objects) – kirotab Oct 23 '15 at 14:25
  • In my code I use to save item method InsertOrReplaceWithChildren(item , recursive: true); And I use to get items method GetAllWithChildren(null,true); And it does not work – Larisa Oct 26 '15 at 06:36

1 Answers1

0

With SQLite-Net, relationships are not fetched automatically, you have to fetch them manually with GetChildren method or use any of the GetWithChildren methods with the recursive flag set to true to load the entire model tree.

Take a look at the RecursiveReadTests and RecursiveWriteTests files in the Integration Tests Project for samples.

UPDATE: You have not set your recursive policy on ClassB ManyToOne relationship to ClassC. Try adding the CascadeOperationsFlag for working with recursive operations:

[ManyToOne(CascadeOperations = CascadeOperation.All)]
public ClassC ClassC { get; set; }

It's also a good idea to use only CascadeRead operation or set ReadOnly mode to true on relationships that are saved manually. For example, your ClassBs property of ClassC doesn't need any write operation:

[OneToMany(ReadOnly = true)]
public List<ClassB> ClassBs { get; set; }

This will avoid you problems where saving ClassC objects may delete relationships when saving an unset property.

redent84
  • 18,901
  • 4
  • 62
  • 85
  • In my code I use to save item method InsertOrReplaceWithChildren(item , recursive: true); And I use to get items method GetAllWithChildren(null,true); And it does not work – Larisa Oct 26 '15 at 06:38
  • Can you share the code where you insert and fetch the elements from database? The models seem fine. – redent84 Oct 26 '15 at 09:00
  • public Boolean SaveItem(T item) { lock (this.locker) { try { this.InsertOrReplaceWithChildren(item , recursive: true); return true; } catch (Exception e) { if (logger != null) { logger.Error(e, String.Format("{0} - Entity:{1}", e.Message, typeof(T).Name)); } return false; } } } – Larisa Oct 26 '15 at 10:54
  • public IList GetItems() { lock (this.locker) { return this.GetAllWithChildren(null,true); } } – Larisa Oct 26 '15 at 10:55