Xamarin Forms SQLLite将OneToOne和OneToMany子对象添加到数据库

问题描述

我正在尝试创建永久的sqllite数据库(安装应用程序后创建表,卸载应用程序时删除数据库

我有一个问题,例如无法保存我的子对象

 public class ObjectInstanceResponseModel : GenericResponseModel
    {
        public ObservableCollection<ObjectInstanceData> ObjectInstances { get; set; }
    }
    public class ObjectInstanceData : GenericResponseModel
    {
        [PrimaryKey,AutoIncrement]
        public int Id { get; set; }

        [JsonProperty("idobjectinstance")]
        public int IdobjectInstance { get; set; }

        [JsonProperty("objectclass_idobjectclass")]
        public int ObjectClassIdobjectClass { get; set; }

        [JsonProperty("objectclassname")]
        public string ObjectClassName { get; set; }

        [JsonProperty("visibilitylevel")]
        public int VisibilityLevel { get; set; }

        [JsonProperty("showname")]
        public bool ShowName { get; set; }

        [JsonProperty("showicon")]
        public bool ShowIcon { get; set; }

        [JsonProperty("creationtime")]
        public DateTimeOffset CreationTime { get; set; }

        [JsonProperty("users_idUsers")]
        public int UsersIdUsers { get; set; }

        [JsonProperty("isfavorite")]
        public bool? IsFavorite { get; set; }

        [OnetoMany("ObjectInstanceDataStrings")]
        [JsonProperty("strings")]
        public List<String> Strings { get; set; }

    }

    public class String
    {
        [PrimaryKey,AutoIncrement]
        [JsonProperty("idobjectparameterstring")]
        public int? IdobjectParameterString { get; set; }

        [ForeignKey(typeof(ObjectInstanceData))]
        public int ObjectInstanceDataStrings { get; set; }

        [JsonProperty("stringvalue")]
        public string StringValue { get; set; }

        [JsonProperty("objectparameterset_idobjectparameterset")]
        public int? ObjectParameterSetIdobjectParameterSet { get; set; }

        [JsonProperty("showinballon")]
        public bool? ShowInBallon { get; set; }

        [JsonProperty("idClassparameter")]
        public int IdClassparameter { get; set; }

        [JsonProperty("classparametername")]
        public string ClassparameterName { get; set; }
    }

因此,尽管表中有一些行创建了Strings,但我的String类始终为空。 我需要为此延迟加载吗?

我通过app.cs中的依赖服务实现了sqllite,如下所示:

public partial class App : Application
{
    public static sqliteConnection DatabaseConnection { get; set; }
    
    public App()
    {
        
        InitializeComponent();

        DatabaseConnection = DependencyService.Get<IConnection>().GetConnection();
        CreateTables();
        
    }

    private void CreateTables()
    {
        DatabaseConnection.CreateTable<ObjectInstanceData>();
        DatabaseConnection.CreateTable<Models.Objects.String>();
    }
        

    protected override void OnStart()
    {
    }
    protected override void OnSleep()
    {
    }

    protected override void OnResume()
    {
    }
}

因此,基本上,逻辑应该是当没有互联网时,使用sql lite(保留本地更改),以及当互联网重新上传时,上传保留在db中的更改,并从表中删除数据。 您注意到我使用的是针对API的响应模型。

因此,我从我的FavoriteObjectviewmodel调用了此

var response = await ApiServiceProvider.GetobjectInstances(null,true);

以及在ApiServiceProvider中:

public static async Task<ObjectInstanceResponseModel> GetobjectInstances(string queryString = null,bool? onlyFavorites = null)
{
    HttpResponseMessage response;

    response = await apiclient.GetAsync(objectInstancesEndpoint);

    var resultContent = await response.Content.ReadAsstringAsync();
    var result = JsonConvert.DeserializeObject<ObservableCollection<ObjectInstanceData>>(resultContent);

    objectInstanceResponse.ObjectInstances = result;

    //after each api call I need to update db

    //delete prevIoUs data,and add fresh data from api
    App.DatabaseConnection.Deleteall<ObjectInstanceData>();
    
    foreach (var item in result)
    {
        App.DatabaseConnection.Insert(item);
        if (item.Strings != null && item.Strings.Count > 0)
        App.DatabaseConnection.InsertAll(item.Strings);
    }

    //I only get the data for ObjectInstanceData,Strings model is empty!
    var objectsResponseDb = App.DatabaseConnection.GetAllWithChildren<ObjectInstanceData>();
    
    objectInstanceResponse.Succeeded = true;

    return objectInstanceResponse;
}

所以,我的问题是:

  • 如果我每次都在App.cs中创建表,那意味着我在用户退出应用程序并再次输入时不存储数据吗?
  • 为什么模型Strings为空?当我调用var strings = App.DatabaseConnection.GetAllWithChildren<Models.Objects.String>();时,可以看到有数据吗?
  • 进行离线“记录”的最佳方法是什么?也许对于sqllite有更好的nuget吗?

解决方法

我对持久性数据库了解不多,但是我可以肯定地说一件事:你的方法是错误的。

  1. 您应该为数据库的逻辑创建单独的类,例如创建表和实例化连接以及其他用于处理数据的方法。
  2. 在App类中,您可以创建数据库类的静态资源,您可以对其进行调用并利用其中的方法。 我不太擅长于说明,但这里是一个非常基本的外观示例:https://docs.microsoft.com/en-us/xamarin/get-started/tutorials/local-database/?tutorial-step=2&tabs=vswin