SQLite Xamarin,如何将具有其他对象的可观察集合的对象保存到数据库



我正在开发一个应用程序来记录棋盘游戏中的得分。这是一个投资组合项目。 游戏由对象表示:

public class GameEntries
{
[PrimaryKey,AutoIncrement]
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public ObservableCollection<PlayerEntries> Players { get; set; }
public bool ScoringMode { get; set; }
public string Date { get; set; }
}

其中播放器对象为:

public class PlayerEntries
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public List<int> points { get; set; }
public string Name { get; set; }
}

我想将游戏对象保存到SQLite数据库中,但它的工作只是没有可观察的集合。

有错误的截图

如何存储游戏条目对象?

此 SQLite 错误是由于您无法存储ObservableCollection类型的数据而导致的。

存储类可用于定义 SQLite 用于在磁盘上存储数据的格式。SQLite 提供了五种主要数据类型,如下所述:

NULL – 它是一个 NULL 值。 整数 – 它是一个整数,以 1、2、3、4、6 或 8 字节存储,具体取决于值。 REAL – 它是一个浮点值,存储为 8 字节浮点数。 文本 – 它是一个字符串,使用数据库编码 (UTF) 存储。 BLOB – 它是一组数据,完全按照输入时存储。

类型亲缘关系概念由 SQLite 在列上支持。任何列所考虑的存储类称为其相关性。SQLite 数据库中每个表的列都分配有以下类型相关性之一:

文本 – 此列捕获空值、文本或 BLOB 的所有数据。 数字 – 此列捕获所有存储类的值。 整数 – 它在 CAST 表达式中有一个异常,其行为方式与具有 NUMERIC 亲和力的列类似。 REAL – 它强制整数值转换为浮动表示形式。并且行为类似于具有数字亲和力的列。 NONE – 具有 NONE 相关性的列不会选择一个存储类而不是其他存储类,也不会将数据从一个存储类更改为另一个存储类。

提示:在这种情况下,您可以将游戏条目表(不带 ObservableCollection)和玩家分开保存,但使用 id 知道您的"游戏条目"是什么"玩家",就像一对一样。

>ObservableCollection<PlayerEntries>不是SQLite数据库值的有效类型。您的ObservableCollection<PlayerEntries>类型与任何 clrType == typeof(XXXX) 语句都不匹配,因此会出现该异常。你需要重新考虑一下类结构,以便能够像这样使用SQLite-net。

如果要使用ObservableCollection<PlayerEntries>,则需要使用具有 OneToMany 关系的 SQLite 扩展。

下面的代码是类类型。

public class GameEntries
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
[OneToMany(CascadeOperations = CascadeOperation.All)]
public ObservableCollection<PlayerEntries> Players { get; set; }
public bool ScoringMode { get; set; }
public string Date { get; set; }
}
public class PlayerEntries
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[ForeignKey(typeof(GameEntries))]
public int GameID { get; set; }
[TextBlob(nameof(Points))]
public List<int> points { get; set; }
public string Points { get; set; }
public string Name { get; set; }
}

数据库的连接和保存操作。

string path;
SQLiteConnection db;
int i = 0;
private void Connect_Clicked(object sender, EventArgs e)
{
var dbName = "OneToManyDb.db3";
path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), dbName);
db = new SQLiteConnection(path);
db.CreateTable<GameEntries>();
db.CreateTable<PlayerEntries>();

}
private void Save_Clicked(object sender, EventArgs e)
{
var game = new GameEntries()
{
Title = "A" + i,
Description = "B" + i
};
db.Insert(game);
var player = new PlayerEntries()
{
Name = "a" + i,
points = new List<int> { 1, 2, 3 }
};
db.Insert(player);
game.Players = new ObservableCollection<PlayerEntries> { player };

db.UpdateWithChildren(game);
db.UpdateWithChildren(player);
//var S = db.GetWithChildren<PlayerEntries>(player.Id);
}

最新更新