简体   繁体   中英

SQLite-Net-Extensions GetWithChildren() Method only reaches first Child Layer

currently I am working with the NuGet SQLite-Net-Extensions in Xamarin Forms and I have encountered a problem for which I can't find a solution.

The Problem: When calling GetWithChildren(primaryKey, recursive: true), the returned object only contains the first child layer. An example can be seen in the following.

The database is built up like this: ER-型号

The equivalent code to this model is provided in the following:

User

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

Contact

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

Entry

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

In my App.cs I am creating the database and use the CreateTable() Method for all three classes. For the sake of this example, in MainPage.xaml.cs there is simply a button, which has a ButtonClicked Method.

In the real Application a process could look like this:

User logs in --> Adds Contact --> At some Point User creates Entry to one of his contacts

To accomplish this procedure in my example, the ButtonClicked Method looks like this:

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

I have set a breakpoint to the bracket that closes the try to inspect the result. In the End, my user looks like this:

用户

Which is absolutely perfect.

However, when I try to get this user from my database, the result looks like this:

在此输入图像描述

I don't know how to resolve this error and hope anyone can help me with this problem. Since this post is very long already, I thank everyone who read this far in advance.

After many tries I finally solved my problem on my own.

在此输入图像描述

Solution:

It could not have been any easier. In my User, Contact and Entry Class I provided my OneToMany and ManyToOne attributes with the CascadeOperation attribute. Example:

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

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

Even though I marked my GetWithChildren() Method as recursive: true, only by applying CascadeOperations it will work properly. More information about SQLite-Net-Extensions and CascadeOperations can be found here:

Source: TwinCoders SQLite-Net-Extensions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM