【问题标题】:Windows Phone 8 optimized insertion into sqlite table from json arrayWindows Phone 8 优化从 json 数组插入 sqlite 表
【发布时间】:2015-05-01 23:54:57
【问题描述】:

我的 Windows Phone 8 应用正在从服务器下载 json 格式的项目列表:

{
  "error":false,
  "lists":[{
    "code":1,
    "name":"item 1"
  },{
    "code":2,
    "name":"item 2"
  },{ 
  ... 
  },{
    "code":100000,
    "name":"item 100000"
  }]
}

应该注意的是,我的应用正在下载 100.000 个项目。

然后我的应用程序解码 json 并迭代每个项目,以便将其插入移动应用程序 SQLite 数据库:

JObject content = JObject.Parse(result);
string jsonLists = content.GetValue("lists").ToString().Trim();
JArray jarrTAR = JArray.Parse(jsonLists);

foreach (JObject content2 in jarrTAR.Children<JObject>())
{
    string code = content2.GetValue("code").ToString().Trim();
    string name = content2.GetValue("name").ToString().Trim();
    ...
    using (var db = new SQLiteConnection(MainPage.DBPath))
    {
        db.RunInTransaction(() =>
        {
            db.Insert(new Table1()
            {
                Code = code,
                Name = name,
                ...
            });
        });
     }
}  

这可行,但将 100.000 个项目插入数据库需要 10 多分钟。

我认为这种方法(将项目逐个插入表中)对于少数项目下载可能是可以接受的,但是当项目数量约为 100.000 时,插入项目的推荐策略应该是什么?

有没有什么方法可以在一个查询中插入全部项目以优化插入时间?

【问题讨论】:

  • 你为什么不使用 RunInTransactionAsync?

标签: c# json sqlite windows-phone-8


【解决方案1】:

大部分时间可能都花在打开/关闭数据库连接上,因为您正在为每个项目创建新连接,然后一次“在事务中运行”一个项目。

您应该首先创建例如List 要插入的对象,然后在事务中插入所有项目。说...

db.RunInTransaction(() => db.InsertAll(items));

您也可以使用async/await 并将此操作作为新的Task 运行。

private async void SomeMethodHere()
{
    ...

    var myItems = new List<Table1>();
    foreach (JObject content2 in jarrTAR.Children<JObject>())
    {
        // create and/or populate collection here
    }

    await InsertAsync("my.sqlite.path", myItems);
}

public Task InsertAsync(string dbPath, IEnumerable<Table1> items)
{
    return Task.Run(() =>
        {
            using (var connection = new SQLiteConnection(dbPath))
                connection.RunInTransaction(() => connection.InsertAll(items));
        });
}

【讨论】:

  • 或者,如果您使用 SQLite-nets SQLiteAsyncConnection,那么您可以将上述方法替换为它们的 *Async 对应方法并完全删除 Task.Run
  • 现在我只需 20 秒即可下载和插入 7000 个项目。我用过:db.RunInTransaction(() => db.InsertAll(items));非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-27
  • 1970-01-01
  • 2010-10-18
  • 1970-01-01
相关资源
最近更新 更多