簡體   English   中英

在 C# 中為 SQLite 形成數據結構的問題

[英]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是一個抽象類是行不通的,因為很難確定數據應該來自哪個表。

它可能會為ActivityWalkSwimRun構建表(如果您使Activity不是抽象的),但 Sqlite.net 擴展將無法創建關系,因此不會拉回數據。

就我個人而言,我不會在您堅持的模型中擁有此屬性的邏輯(您可能這樣做是為了簡化問題,並且有更多邏輯):

public override double OutputKms { get { return Input * 3; } }

您可以將WalkRunSwim的乘數重構為屬性或在活動類中存儲活動類型枚舉,而不是將其抽象為:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM