首页 > 解决方案 > SQLite-Net-Extensions GetWithChildren() 方法只到达第一个子层

问题描述

目前我正在使用 Xamarin Forms 中的 NuGet SQLite-Net-Extensions 并且遇到了一个我找不到解决方案的问题。

问题:调用GetWithChildren(primaryKey, recursive: true)时,返回的对象只包含第一个子层。一个例子可以在下面看到。

数据库是这样建立的: ER模型

下面提供了此模型的等效代码:

用户

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

我已经在括号中设置了一个断点来关闭尝试检查结果。最后,我的用户看起来像这样:

用户

这绝对是完美的。

但是,当我尝试从我的数据库中获取此用户时,结果如下所示:

在此处输入图像描述

我不知道如何解决这个错误,希望任何人都可以帮助我解决这个问题。由于这篇文章已经很长了,我感谢所有提前阅读这篇文章的人。

标签: c#databasexamarin.formssqlite-net

解决方案


经过多次尝试,我终于自己解决了我的问题。

在此处输入图像描述

解决方案:

这再简单不过了。在我的用户、联系人和条目类中,我为我的 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


推荐阅读