Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLite Net Extensions OneToMany relationship not inserting/saving/updating Children

I'm attempting to use SQLite Net Extensions to do a note taking app for games, it uses 3 layers of models, Game [1 has many *] Character [1 has many *] Note [1 applies to *] Character

I am using Xamarin in Visual Studio Community 2015 and installed SQLiteNetExtensions using the NuGet package manager.

I'm not past the first level of relationships between Game and character yet, and Inserting into the database (whether via initial insert and then update, or using InsertWithChildren recursively) is not updating the Characters in the Game object. It just results in a null object for the List<CharacterModel> inside GameModel. However both the game and the characters are making it on the database.

Abstract base model

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

Game Model

[Table("Game")]
public class GameModel : IdentifiableModel
{
    [MaxLength(64)]
    public string Name { get; set; }

    [OneToMany]
    public List<CharacterModel> Characters { get; set; }
}

Character Model

[Table("Characters")]
public class CharacterModel : IdentifiableModel
{
    [ForeignKey(typeof (GameModel))]
    public int GameId { get; set; }

    [ManyToOne]
    public GameModel Game { get; set; }

    public string FullName { get; set; }
    public string ShortName { get; set; }
}

To test inserting into the database I do this on my Main activity:

var game =
    new GameModel
    {
        Name = "Game"
    };

database.Insert(game);

var characters = new List<CharacterModel>
{
    new CharacterModel
    {
        FullName = "Dude"
    },
    new CharacterModel
    {
        FullName = "Dudette"
    }
};

database.InsertAll(characters);

game.Characters = characters;

database.UpdateWithChildren(game);

var testGame = database.GetAll<GameModel>().FirstOrDefault();
var testCharacter = database.GetAll<CharacterModel>().FirstOrDefault();

Console.WriteLine(testGame.Id + " " + testGame.Name);
Console.WriteLine(testCharacter.Id + " " + testCharacter.FullName + " " + testCharacter.GameId);
//testGame.Characters;  // THIS IS NULL.
//testCharacter.Game;  // THIS IS NULL.

I'm at a loss at where to begin sorting this and would appreciate some help getting it up and running.


Edit: Using a non-inherited Primary Key made no difference at all. Still no data in testGame.Characters or testCharacter.Game

like image 859
Tom 'Blue' Piddock Avatar asked Dec 25 '22 10:12

Tom 'Blue' Piddock


2 Answers

SQLite-Net Extensions extends SQLite.Net with additional methods that loads and writes relationships. You are writing the relationship to database using UpdateWithChildren method, but you are not loading the relationship from database because GetAll is a plain SQLite.Net method.

Try using any *WithChildren variant of SQLite.Net methods, for example:

var testGame = database.GetAllWithChildren<GameModel>().FirstOrDefault();

or:

var testGame = database.GetWithChildren<GameModel>(game.Id);

Alternatively you can load relationships of already existing objects calling GetChildren method:

var testGame = database.GetAll<GameModel>().FirstOrDefault();
testGame.GetChildren();
like image 62
redent84 Avatar answered Jan 14 '23 07:01

redent84


I had the same problem due to missing CascadeOperations = CascadeOperation.All. Add the instruction as below resolve my issue

[OneToMany(CascadeOperations = CascadeOperation.All)]
like image 28
CodeSi Avatar answered Jan 14 '23 07:01

CodeSi