Метод GetWithChildren () SQLite-Net-Extensions достигает только первого дочернего уровня - PullRequest
0 голосов
/ 16 марта 2019

В настоящее время я работаю с NuGet SQLite-Net-Extensions в формах Xamarin и столкнулся с проблемой, для которой не могу найти решение.

Проблема: при вызове GetWithChildren (primaryKey, recursive: true) возвращаемый объект содержит только первый дочерний слой.Пример можно увидеть в следующем:

База данных создается следующим образом: ER-Model

Эквивалентный код для этой модели приведен ниже:

Пользователь

namespace DatabaseTest
{
[Table("Users")]
public class User
{
    [PrimaryKey,AutoIncrement]
    public int Id { get; set; }

    public string Name { get; set; }

    [OneToMany]
    public List<Contact> Contacts { get; set; }
}
}

Контакт

namespace DatabaseTest
{
[Table("Contacts")]
public class Contact
{
    [PrimaryKey,AutoIncrement]
    public int Id { get; set; }

    public string Name { get; set; }

    [OneToMany]
    public List<Entry> Entries { get; set; }

    [ForeignKey(typeof(User))]
    public int UserID { get; set; }

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

Запись

namespace DatabaseTest
{
[Table("Entries")]
public class Entry
{
    [PrimaryKey,AutoIncrement]
    public int Id { get; set; }

    public float Amount { get; set; }

    [ForeignKey(typeof(Contact))]
    public int ContactId { get; set; }

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

В моем App.cs я создаю базу данных и использую CreateTable() Метод для всех трех классов.Ради этого примера в MainPage.xaml.cs есть просто кнопка с методом ButtonClicked.

В реальном приложении процесс может выглядеть так:

Журналы пользователяв -> Добавляет контакт -> В какой-то момент пользователь создает запись для одного из своих контактов

Чтобы выполнить эту процедуру в моем примере, метод ButtonClicked выглядит следующим образом:

void ButtonClicked(object sender, EventArgs e)
    {
        try
        {
            User user = new User()
            {
                Name = "Test user"
            };
            Contact contact = new Contact()
            {
                Name = "First contact"
            };
            Entry entry1 = new Entry()
            {
                Amount = 10F
            };
            Entry entry2 = new Entry()
            {
                Amount = 20F
            };
            App.Database.Insert(user);
            if (user.Contacts==null)
            {
                user.Contacts = new List<Contact>();
            }
            App.Database.Insert(contact);
            user.Contacts.Add(contact);
            App.Database.UpdateWithChildren(user);
            if (contact.Entries==null)
            {
                contact.Entries = new List<Entry>();
            }
            App.Database.Insert(entry1);
            App.Database.Insert(entry2);
            contact.Entries.Add(entry1);
            contact.Entries.Add(entry2);
            App.Database.UpdateWithChildren(contact);
            App.Database.UpdateWithChildren(user);
            var test = App.Database.GetWithChildren<User>(user.Id, recursive: true);
            var test2 = App.Database.GetAllWithChildren<Contact>();
            var test3 = App.Database.GetAllWithChildren<Entry>();
        } catch (Exception ex)
        {
            Debug.Print(ex.Message);
        }
    }

Я установил точку останова на скобке, которая закрывает попытку проверить результат.В конце концов, мой пользователь выглядит так:

User

Что абсолютно идеально.

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

enter image description here

Я не знаю, как решить эту ошибку, и надеюсь, что кто-нибудь может мне помочь с этимпроблема.Поскольку этот пост уже очень длинный, я благодарю всех, кто прочитал это заранее.

1 Ответ

0 голосов
/ 17 марта 2019

После многих попыток я наконец решил свою проблему самостоятельно.

enter image description here

Решение:

Это не могло бытьПолегче.В классе User, Contact и Entry я предоставил атрибуты OneToMany и ManyToOne атрибутом CascadeOperation.Пример:

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

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

Несмотря на то, что я пометил мой метод GetWithChildren () как рекурсивный: true, только при применении CascadeOperations он будет работать правильно.Дополнительную информацию о SQLite-Net-Extensions и CascadeOperations можно найти здесь:

Источник: TwinCoders SQLite-Net-Extensions

...