[英]Trouble forming data structure for SQLite in C#
我正在嘗試構建一個非常簡單的 Xamarin 應用程序,其功能類似於鍛煉/日計划。 SQLite 數據庫應該保存一個“Day”s 表,並且每一天都應該與一個“Activity”s 表相關聯,它可以查詢那幾天的“Activity”s。 這些“活動”應該屬於某種類型,為簡單起見,我們可以說“步行”、“跑步”或“游泳”。 然后,用戶應該能夠對該數據庫執行基本的 CRUD 操作,以回憶前幾天及其相關活動。 理想情況下,使用 SQLiteNetExtensions 庫,我應該能夠進行簡單的調用來檢索數據:
SQLiteAsyncConnection connection = DependencyService.Get<ISQLiteDb>().GetConnection();
var day = await connection.GetWithChildrenAsync<Day>(primaryKey, recursive = true);
模型(簡化):
using SQLite;
using SQLiteNetExtensions.Attributes;
using System;
using System.Collections.Generic;
public class Day {
public Day()
{
Date = DateTime.Now;
}
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public DateTime Date { get; set; }
[OneToMany]
public List<Activity> Activities { get; set; }
}
public abstract class Activity
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[ManyToOne(typeof(Day))]
public Day Day { get; set; }
[ForeignKey]
public int DayRefId { get; set; }
public double Input { get; set; }
public virtual double OutputKms { get; set; }
}
public class Walk : Activity
{
public override double OutputKms { get { return Input * 3; } }
}
public class Run: Activity
{
public override double OutputKms { get { return Input * 5; } }
}
public class Swim: Activity
{
public override double OutputKms { get { return Input * 3; } }
}
我正在使用以下代碼初始化我的數據庫:
using SQLite;
using Xamarin.Forms;
using SQLiteNetExtensionsAsync.Extensions;
public async static Task InitDb()
{
SQLiteAsyncConnection connection = DependencyService.Get<ISQLiteDb>().GetConnection();
await connection.CreateTableAsync<Day>();
await connection.CreateTableAsync<Activity>();
await connection.CreateTableAsync<Walk>();
await connection.CreateTableAsync<Run>();
await connection.CreateTableAsync<Swim>();
}
問題是 SQLite 不喜歡基於抽象類的表。 在我嘗試創建“活動”表的行中,我收到以下編譯錯誤:
錯誤 CS0310“活動”必須是具有公共無參數構造函數的非抽象類型才能將其用作參數“T”
我知道實體框架支持使用抽象類,但如果可能,我寧願堅持使用 SQLite。
這似乎是一個簡單的問題,但對我來說,在不求助於最簡單的 poco 對象和編寫大量重復代碼的情況下解決起來很棘手。
我的問題是如何更好地重構我的代碼,我可以使用哪些庫或我可以編寫什么樣的映射來實現這一點。 感謝任何反饋。 謝謝!
Sqlite.net 和 Sqlite.net 擴展中的所有類型都是T : new()
所以你不能使用抽象類。 像這樣的代碼:
[OneToMany]
public List<Activity> Activities { get; set; }
其中Activity
是一個抽象類是行不通的,因為很難確定數據應該來自哪個表。
它可能會為Activity
、 Walk
、 Swim
、 Run
構建表(如果您使Activity
不是抽象的),但 Sqlite.net 擴展將無法創建關系,因此不會拉回數據。
就我個人而言,我不會在您堅持的模型中擁有此屬性的邏輯(您可能這樣做是為了簡化問題,並且有更多邏輯):
public override double OutputKms { get { return Input * 3; } }
您可以將Walk
、 Run
、 Swim
的乘數重構為屬性或在活動類中存儲活動類型枚舉,而不是將其抽象為:
public class Activity
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
[ManyToOne(typeof(Day))]
public Day Day { get; set; }
[ForeignKey]
public int DayRefId { get; set; }
public double Input { get; set; }
public ActivityType ActivityType { get; set; }
}
public enum ActivityType
{
Walk,
Run,
Swim
}
另一種選擇是為 Pocos 數據庫創建不同的模型,這些模型映射到更復雜的應用程序模型。 可能使用 AutoMapper
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.