Xamarin / C#-以编程方式将数据插入多个表的SQLite数据库中?

时间:2019-10-15 05:28:54

标签: c# sqlite xamarin

我的Xamarin应用程序从API中提取数据,并将其插入到SQLite表中。该API当前定义了9个表,因此我的应用程序中有9个与这些表匹配的类。我使用了该问题的可接受答案中的代码片段: Getting all types in a namespace via reflection

下面是我的代码,使用答案中的代码段和我尝试构建的foreach循环来插入数据。

string nspace = "App.Tables";
            var q = from t in Assembly.GetExecutingAssembly().GetTypes()
                    where t.IsClass && t.Namespace == nspace
                    select t.Name; // Getting list of classes as IEnumerable
            var L = q.ToList(); // Converting to List

            foreach (var name in L) // Inserts data for every class found
            {
                var response = await httpClient.Value.GetStringAsync("http://website.com/api/" + name + "s"); // Substitutes each class name into API url
                var data = JsonConvert.DeserializeObject<List<TableName>>(response); // Deserializes into List
                using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation)) // Opens database connection
                {
                    conn.CreateTable<TableName>(); // Create table
                    conn.DeleteAll<TableName>(); // Delete all old data
                    conn.InsertAll(data); // Inserts new data
                }
            }

我不知道应该使用哪个TableName来获取列表中每个项目的正确类。例如:说列表包含字符串Table1,Table2和Table3-它从App.Tables命名空间获得了这些字符串,命名空间包含三个独立的类,分别称为Table1,Table2和Table3。当代码的第一部分获得列表并将其存储为变量L时,它应获取L中每个“名称”变量的数据,然后将其插入匹配表中。如何将其引用到表中?

1 个答案:

答案 0 :(得分:1)

  

在我给出答案之前,我想告诉你我不   建议通过反射更新表-表应包含   逻辑上不同的实体,因此批量删除和更新它们是   有点怪。这是我绝不会发生的少数事件之一   解决方法一一键入表的更新。但是那些是   只是我的两分钱...当然,如果我有一千张桌子   不会忍受。

     

这种反射也使您的代码难以遵循和跟踪-考虑一下如何搜索CreateTable<ExampleClass>()方法的用法?在此段代码中,您永远都不会追溯它-或仅通过努力才能找到它。

所以回答您的问题...

您首先要获得方法组,然后根据类型创建它的通用版本。我认为对于所需的部分,无需从Type转换为string,因为您需要转换回Type

using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation)) {
    MethodInfo nonGenMethodCreate = typeof(SQLiteConnection).GetMethod("CreateTable");
    MethodInfo nonGenMethodDeleteAll = typeof(SQLiteConnection).GetMethod("DeleteAll");
    MethodInfo nonGenMethodInsertAll = typeof(SQLiteConnection).GetMethod("InsertAll");

    foreach(Type t in Assembly.GetExecutingAssembly.GetTypes()) {
        MethodInfo genMethodCreate = nonGenMethodCreate.MakeGenericMethod(t);
        MethodInfo genMethodDeleteAll = nonGenMethodDeleteAll.MakeGenericMethod(t);
        MethodInfo genMethodInsertAll = nonGenMethodInsertAll.MakeGenericMethod(t);

        genMethodCreate.Invoke(conn, null);
        genMethodDeleteAll.Invoke(conn, null);
        genMethodInsertAll.Invoke(conn, new[] { data });

    }
}