繁体   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