【问题标题】:saving ObservableCollection<MyClass> to SQLite or similar, Xamarin Forms将 ObservableCollection<MyClass> 保存到 SQLite 或类似的 Xamarin Forms
【发布时间】:2017-12-24 19:14:18
【问题描述】:

我的应用中有多个 ObservableCollections,我想对其进行保存、编辑等操作。但由于它们是我自己的类的集合,SQLite 无法识别它们。保存论文的最佳方法是什么?或者我做错了什么。

有点像这样:

在我的App中:(当然里面还有更多代码)

public partial class App : Application 
{ 
  static MyDatabase database; 
  
  public static MyDatabase Database 
  { 
    get 
    { 
      if (database == null) 
      { 
        database = new MyDatabase(DependencyService.Get
<IFileHelper>().GetLocalFilePath("MyListSQLite.db3")); 
      } 
      return database; 
    } 
  } 
}

我的数据库:

public class MyDatabase
{
  readonly SQLiteAsyncConnection database;

  public MyDatabase(string dbPath)
  {
    database = new SQLiteAsyncConnection(dbPath);
    database.CreateTableAsync<MyClass>().Wait();
  }

  public Task<List<MyClass>> GetItemsAsync()
  {
    return database.Table<MyClass>().ToListAsync();
  }

	public Task<MyClass> GetItemAsync(int id)
	{
		return database.Table<MyClass>().Where(i => i.ID == id).FirstOrDefaultAsync();
	}

	public Task<int> SaveItemAsync(MyClass item)
	{
		if (item.ID != 0)
		{
			return database.UpdateAsync(item);
		}
		else
		{
			return database.InsertAsync(item);
		}
	}

	public Task<int> DeleteItemAsync(MyClass item)
	{
		return database.DeleteAsync(item);
	}

}

我的班级:

public class MyClass : ObservableCollection<MyOtherClass>
{ 
  [PrimaryKey, AutoIncrement] 
  public int ID { get; set; } 
}

我的其他类:

public class MyOtherClass : BindableObject
    {
        [PrimaryKey, AutoIncrement]
        public int ID { get; set; }


        public static readonly BindableProperty ListNbrProperty =
            BindableProperty.Create("ListNbr", typeof(int), typeof(MyOtherClass), default(int));

		public int ListNbr
		{
			get { return (int)GetValue(ListNbrProperty); }
			set { SetValue(ListNbrProperty, value); }
		}

        public bool IsMaster { get; set; }

		public static readonly BindableProperty ResizedPathProperty =
            BindableProperty.Create("ResizedPath", typeof(String), typeof(MyOtherClass), default(String));

		public String ResizedPath
		{
            get { return (String)GetValue(ResizedPathProperty); }
			set { SetValue(ResizedPathProperty, value); }
		}
...
}

【问题讨论】:

  • 我想这不是最好的方法。似乎您想保存 MyOtherClass 对象-一旦您的收藏没有理由存在,除了展示您的对象(只是为了展示或处理某些东西)-因此您可以使用database.InsertAlldatabase.UpdateAll 在您的数据库类。

标签: database sqlite xamarin.forms observablecollection


【解决方案1】:

在我们的大多数应用程序中,对于复杂对象,我们只是将它们序列化为 Json,以便它们可以存储为字符串(在您的情况下为 NVarChar(MAX) ?)。我们并不总是使用 SQL,有时我们使用原生项目自己的存储机制(即 iOS 的 NSUserDefaults)

using Newtonsoft.Json;

    public static async Task<bool> CacheList (ObservableList<string> MyList)
    {
        try
        {
            var json = JsonConvert.SerializeObject(MyList);

            // you dont need to encrypt the string, but we deal with some 
            // sensitive data so we have a seperate cryptography class that handles this.

            var EncryptedJson = Cryptography.Crypto.Encrypt(json, Key);

            // Now you have your serialised object simply store it into your database using whatever method you usually user

            [Store to SQLdatabase Code goes here]

            return await Task.FromResult(true);
        }
        catch (Exception genEx)
        {
            var Error = genEx.Message;
            return await Task.FromResult(false);
        }
    }

然后检索它:

    public static async Task<ObservableList<string>> RetrieveList (string key)
    {
        try
        {
            // Retrieve your json string from your sql database

            [retrieve from SQLdatabase Code goes here - returns EncryptedJson]

            // In our case we decrypt it
            var DecryptedJson = Cryptography.Crypto.Decrypt(EncryptedJson, Key);
            var DeSerialisedData = JsonConvert.DeserializeObject<ObservableList<string>>(DecryptedJson);

            return await Task.FromResult(DeSerialisedData ?? new ObservableList<string>());

        }
        catch (Exception genEx)
        {
            var Error = genEx.Message;
            return await Task.FromResult(new ObservableList<string>());
        }
    }

以上内容不是复制和粘贴,而是可以工作的示例,它实际上是我们在应用程序中使用的高级概念。

【讨论】:

  • 很好,我也在考虑 json,但不知道哪一种是最好的方法,因为我没有这方面的经验。刚刚使MyClass 为每个ObservableCollection 获取一个ID,但是是否可以像您在上面所做的那样使用&lt;ObservableList&lt;MyOtherClass&gt;
  • 没错,json SerializeObject 方法会以准确的 json 表示形式将复杂的对象分解为它们的属性,所以请发疯。 =)
猜你喜欢
  • 1970-01-01
  • 2016-06-17
  • 1970-01-01
  • 2020-11-01
  • 2016-10-03
  • 2018-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多