我在毛伊岛应用程序中有一个数据库,有两个表。第一个表设置了这样的类:
public class Groups
{
[PrimaryKey, AutoIncrement]
public long Id { get; set; }
public string? GrpName { get; set; }
}
另一个表是用此类创建的:
public class Sites
{
[PrimaryKey, AutoIncrement]
public long Id { get; set; }
public string? Title { get; set; }
public string? SiteAddr { get; set; }
public long GrpId { get; set; } // The Id number matching the Group Id
public string? Notes { get; set; }
}
我想要做的是从我已经创建的数据网格中选择一个或多个组,并删除通过 GrpId 字段链接到组表的所有组和站点记录。
我在 LINQ 中进行了研究,认为我可以以与 MySql 类似的方式删除站点记录,但我就是无法理解它。有什么建议吗?
据我了解,如果 UI 操作从视图中删除了
Group
对象,则关系 Site
对象应该从数据库中永久删除(或者可能只是从视图中的可见性中删除)。
无论哪种方式,人们都可以在绑定上下文中定义此行为,在其视图中添加和删除关系
Site
对象,作为对 CollectionChanged.Add
集合触发的 CollectionChanged.Remove
Groups
事件的响应。
// <PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
using SQLite;
class MainPageBinding : INotifyPropertyChanged
{
public MainPageBinding()
{
TestCommand = new Command(OnTest);
Groups.CollectionChanged += (sender, e) =>
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Remove:
if (e.OldItems != null)
{
foreach (Group group in e.OldItems)
{
InMemoryDatabase.Delete(group);
foreach(
var site
in InMemoryDatabase.Table<Site>()
.Where(_=>_.GrpId == group.Id))
{
Sites.Remove(site);
InMemoryDatabase.Delete(site);
}
}
}
break;
case NotifyCollectionChangedAction.Add:
if (e.NewItems != null)
{
foreach (Group group in e.NewItems)
{
foreach (
Site site in
InMemoryDatabase.Table<Site>()
.Where(_ => _.GrpId == group.Id))
{
Sites.Add(site);
}
}
}
break;
}
};
// Query the database to populate the CollectionView controls on MainView
foreach (Group group in InMemoryDatabase.Table<Group>()) Groups.Add(group);
}
#region T E S T I N G
// For testing purposes:
// Using an in-memory SQLite database instead of .db file
SQLiteConnection InMemoryDatabase
{
get
{
if(_singleton == null)
{
_singleton = new SQLiteConnection(":memory:");
InMemoryDatabase.CreateTable<Group>();
InMemoryDatabase.CreateTable<Site>();
var groupA = new Group { GrpName = "GroupA" };
InMemoryDatabase.Insert(groupA);
InMemoryDatabase.Insert(new Site { Title = "GroupA.Site1", GrpId = groupA.Id });
InMemoryDatabase.Insert(new Site { Title = "GroupA.Site2", GrpId = groupA.Id });
var groupB = new Group { GrpName = "GroupB" };
InMemoryDatabase.Insert(groupB);
InMemoryDatabase.Insert(new Site { Title = "GroupB.Site1", GrpId = groupB.Id });
InMemoryDatabase.Insert(new Site { Title = "GroupB.Site2", GrpId = groupB.Id });
}
return _singleton;
}
}
SQLiteConnection? _singleton = null;
#endregion T E S T I N G
}
[Table("groups")]
public class Group : IEquatable<Group>
{
// Consider making this key unique at the point of
// instantiation rather than the point of insertion.
[PrimaryKey]
public string Id { get; set; } = Guid.NewGuid().ToString().ToUpper();
[Unique]
public string? GrpName { get; set; }
public bool Equals(Group? other) =>
Id == other?.Id;
public override string ToString() => GrpName ?? "Default";
}
[Table("site")]
public class Site : IEquatable<Site>
{
[PrimaryKey]
public string Id { get; set; } = Guid.NewGuid().ToString().ToUpper();
[Unique]
public string? Title { get; set; }
public string? SiteAddr { get; set; }
public string? GrpId { get; set; } // The Id number matching the Group Id
public string? Notes { get; set; }
public bool Equals(Site? other) =>
Id == other?.Id;
public override string ToString() => Title ?? "Default";
}