Связь OneToMany с расширениями SQLite Net Extensions не вставляет / не сохраняет / не обновляет дочерние элементы

Я пытаюсь использовать SQLite Net Extensions, чтобы сделать приложение для заметок в играх, оно использует 3 уровня моделей, Game [1 has many *] Character [1 has many *] Note [1 applies to *] Character

Я использую Xamarin в Visual Studio Community 2015 и установил SQLiteNetExtensions с помощью диспетчера пакетов NuGet.

Я еще не прошел первый уровень отношений между Game и персонажем, и вставка в базу данных (через начальную вставку с последующим обновлением или рекурсивное использование InsertWithChildren) не обновляет персонажей в объекте Game. Это просто приводит к нулевому объекту для List<CharacterModel> внутри GameModel. Однако и игра, и персонажи вносят это в базу данных.

Абстрактная базовая модель

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

Модель игры

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

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

Модель персонажа

[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; }
}

Чтобы проверить вставку в базу данных, я делаю это в своем основном действии:

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.

Я не понимаю, с чего начать сортировку этого, и был бы признателен за помощь в его настройке и запуске.


Изменить. Использование ненаследственного первичного ключа вообще не имело никакого значения. По-прежнему нет данных в testGame.Characters или testCharacter.Game


person Tom 'Blue' Piddock    schedule 20.01.2016    source источник
comment
В рамках абстрактной базовой модели все первичные ключи являются свойством Id в расширенном классе.   -  person Tom 'Blue' Piddock    schedule 20.01.2016
comment
Я не уверен, работает ли наследование ПК или нет. Я тоже сомневаюсь, что это имеет значение.   -  person NoChance    schedule 20.01.2016
comment
Я посмотрю, работает ли он без него, хотя в учебнике Xamarin используется унаследованный PK: developer.xamarin.com/guides/cross-platform/   -  person Tom 'Blue' Piddock    schedule 20.01.2016
comment
@NoChance - без разницы, обновил вопрос.   -  person Tom 'Blue' Piddock    schedule 20.01.2016
comment
Спасибо. для обновления.   -  person NoChance    schedule 20.01.2016
comment
Я вижу, что вы вставляете символы, но где для них родительская «игра»? Как можно использовать значение PK игры без ссылки на Game?   -  person NoChance    schedule 20.01.2016
comment
Я просто ссылаюсь на игру, используя тот же объект, чтобы убедиться, что я выбираю правильную игру, ссылки PK будут храниться во внешнем интерфейсе позже для использования.   -  person Tom 'Blue' Piddock    schedule 20.01.2016


Ответы (2)


SQLite-Net Extensions расширяет SQLite.Net дополнительными методами, которые загружают и записывают отношения. Вы пишете отношение к базе данных, используя метод UpdateWithChildren, но не загружаете отношения из базы данных, потому что GetAll - это простой метод SQLite.Net.

Попробуйте использовать любой *WithChildren вариант методов SQLite.Net, например:

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

or:

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

В качестве альтернативы вы можете загрузить отношения уже существующих объектов, вызывая метод GetChildren:

var testGame = database.GetAll<GameModel>().FirstOrDefault();
testGame.GetChildren();
person redent84    schedule 20.01.2016
comment
Пятно на. Теперь он работает. У меня возникла небольшая проблема после переключения методов с этой ошибкой: bugzilla.xamarin.com/show_bug .cgi? id = 32622 решения сработали и устранили проблему. - person Tom 'Blue' Piddock; 20.01.2016

У меня была такая же проблема из-за отсутствия CascadeOperations = CascadeOperation.All. Добавьте инструкцию, как показано ниже, решите мою проблему

[OneToMany(CascadeOperations = CascadeOperation.All)]
person CodeSi    schedule 08.02.2018
comment
Удивительно, я боролся с этим весь день, и у меня был установлен параметр CascadeOperation.Delete, который был бесполезен, пока я не перешел на All. Спасибо. - person paul-2011; 04.02.2021