SQLite-Net 扩展如何正确地递归更新对象
SQLite-Net Extensions how to correctly update object recursively
我正在使用 SQLite-Net PCL 和 SQLite-Net 扩展一起使用 Xamarin 开发应用程序。
我有两个 类 A
和 B
之间的一对多关系,定义如下:
public class A
{
[PrimaryKey, AutoIncrement]
public int Id
{
get;
set;
}
public string Name
{
get;
set;
}
[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<B> Sons
{
get;
set;
}
public A()
{
}
public A(string name, List<B> sons)
{
Name = name;
Sons = sons;
}
}
public class B
{
[PrimaryKey, AutoIncrement]
public int Id
{
get;
set;
}
public string Name
{
get;
set;
}
[ForeignKey(typeof(A))]
public int FatherId
{
get;
set;
}
[ManyToOne]
public A Father
{
get;
set;
}
public B()
{
}
public B(string name)
{
Name = name;
}
}
我想做的是从数据库中检索类型为 A
的对象,删除类型为 B
的 Sons
对象之一并相应地更新数据库.这是我试过的:
var sons = new List<B>
{
new B("uno"),
new B("due"),
new B("tre"),
};
one = new A("padre", sons);
using (var conn = DatabaseStore.GetConnection())
{
conn.DeleteAll<A>();
conn.DeleteAll<B>();
conn.InsertWithChildren(one, true);
A retrieved = conn.GetWithChildren<A>(one.Id);
retrieved.Sons.RemoveAt(1);
}
using (var conn = DatabaseStore.GetConnection())
{
var retrieved = conn.GetWithChildren<A>(one.Id);
retrieved.Sons.RemoveAt(1); //"due"
//conn.UpdateWithChildren(retrieved);
conn.InsertOrReplaceWithChildren(retrieved, true);
}
问题是 UpdateWithChildren
和 InsertOrReplaceWithChildren
对象并没有真正从数据库中删除,而只是它的外键为空。是否可以让它删除 son
对象?
您并不是真的要删除任何对象。您只是删除了两个对象之间的关系,但没有什么能阻止您拥有更多与其中任何对象相关的对象,因此删除任何对象都是不正确的,因为您可能会破坏其他关系。
应该是这样的:
using (var conn = DatabaseStore.GetConnection())
{
var retrieved = conn.GetWithChildren<A>(one.Id);
var due = retrieved.Sons[1];
// This is not required if the foreign key is in the other end,
// but it would be the usual way for any other scenario
// retrieved.Sons.Remove(due);
// conn.UpdateWithChildren(retrieved);
// Then delete the object if it's no longer required to exist in the database
conn.delete(due);
}
我正在使用 SQLite-Net PCL 和 SQLite-Net 扩展一起使用 Xamarin 开发应用程序。
我有两个 类 A
和 B
之间的一对多关系,定义如下:
public class A
{
[PrimaryKey, AutoIncrement]
public int Id
{
get;
set;
}
public string Name
{
get;
set;
}
[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<B> Sons
{
get;
set;
}
public A()
{
}
public A(string name, List<B> sons)
{
Name = name;
Sons = sons;
}
}
public class B
{
[PrimaryKey, AutoIncrement]
public int Id
{
get;
set;
}
public string Name
{
get;
set;
}
[ForeignKey(typeof(A))]
public int FatherId
{
get;
set;
}
[ManyToOne]
public A Father
{
get;
set;
}
public B()
{
}
public B(string name)
{
Name = name;
}
}
我想做的是从数据库中检索类型为 A
的对象,删除类型为 B
的 Sons
对象之一并相应地更新数据库.这是我试过的:
var sons = new List<B>
{
new B("uno"),
new B("due"),
new B("tre"),
};
one = new A("padre", sons);
using (var conn = DatabaseStore.GetConnection())
{
conn.DeleteAll<A>();
conn.DeleteAll<B>();
conn.InsertWithChildren(one, true);
A retrieved = conn.GetWithChildren<A>(one.Id);
retrieved.Sons.RemoveAt(1);
}
using (var conn = DatabaseStore.GetConnection())
{
var retrieved = conn.GetWithChildren<A>(one.Id);
retrieved.Sons.RemoveAt(1); //"due"
//conn.UpdateWithChildren(retrieved);
conn.InsertOrReplaceWithChildren(retrieved, true);
}
问题是 UpdateWithChildren
和 InsertOrReplaceWithChildren
对象并没有真正从数据库中删除,而只是它的外键为空。是否可以让它删除 son
对象?
您并不是真的要删除任何对象。您只是删除了两个对象之间的关系,但没有什么能阻止您拥有更多与其中任何对象相关的对象,因此删除任何对象都是不正确的,因为您可能会破坏其他关系。
应该是这样的:
using (var conn = DatabaseStore.GetConnection())
{
var retrieved = conn.GetWithChildren<A>(one.Id);
var due = retrieved.Sons[1];
// This is not required if the foreign key is in the other end,
// but it would be the usual way for any other scenario
// retrieved.Sons.Remove(due);
// conn.UpdateWithChildren(retrieved);
// Then delete the object if it's no longer required to exist in the database
conn.delete(due);
}