SQLite-Net-Extensions GetWithChildren() 方法只到达第一个子层
SQLite-Net-Extensions GetWithChildren() Method only reaches first Child Layer
目前我正在使用 Xamarin Forms 中的 NuGet SQLite-Net-Extensions,我遇到了一个我找不到解决方案的问题。
问题:调用GetWithChildren(primaryKey, recursive: true) 时,返回的对象只包含第一个子层。下面是一个例子。
数据库是这样建立的:
下面提供了此模型的等效代码:
用户
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);
}
}
我已经在关闭尝试检查结果的括号中设置了一个断点。最后,我的用户看起来像这样:
绝对完美。
但是,当我尝试从我的数据库中获取该用户时,结果如下所示:
我不知道如何解决这个错误,希望有人能帮我解决这个问题。
由于这篇 post 已经很长了,我感谢所有提前阅读这篇文章的人。
经过多次尝试,我终于自己解决了我的问题。
解决方案:
再简单不过了。在我的用户、联系人和条目 Class 中,我为我的 OneToMany 和 ManyToOne 属性提供了 CascadeOperation 属性。示例:
[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<Entry> Entries { get; set; }
[ManyToOne(CascadeOperations = CascadeOperation.All)]
public User User { get; set; }
尽管我将我的 GetWithChildren() 方法标记为递归:是的,但只有应用 CascadeOperations 它才能正常工作。可以在此处找到有关 SQLite-Net-Extensions 和 CascadeOperations 的更多信息:
目前我正在使用 Xamarin Forms 中的 NuGet SQLite-Net-Extensions,我遇到了一个我找不到解决方案的问题。
问题:调用GetWithChildren(primaryKey, recursive: true) 时,返回的对象只包含第一个子层。下面是一个例子。
数据库是这样建立的:
下面提供了此模型的等效代码:
用户
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);
}
}
我已经在关闭尝试检查结果的括号中设置了一个断点。最后,我的用户看起来像这样:
绝对完美。
但是,当我尝试从我的数据库中获取该用户时,结果如下所示:
我不知道如何解决这个错误,希望有人能帮我解决这个问题。 由于这篇 post 已经很长了,我感谢所有提前阅读这篇文章的人。
经过多次尝试,我终于自己解决了我的问题。
解决方案:
再简单不过了。在我的用户、联系人和条目 Class 中,我为我的 OneToMany 和 ManyToOne 属性提供了 CascadeOperation 属性。示例:
[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<Entry> Entries { get; set; }
[ManyToOne(CascadeOperations = CascadeOperation.All)]
public User User { get; set; }
尽管我将我的 GetWithChildren() 方法标记为递归:是的,但只有应用 CascadeOperations 它才能正常工作。可以在此处找到有关 SQLite-Net-Extensions 和 CascadeOperations 的更多信息: