2017-07-18 87 views
0

我有以下的JSON的樣板工程,這是我無法改變:C#反序列化,然後插入到SQLite數據庫

[ 
    { 
     "id": 3, 
     "description": "Project A" 
    }, 
    { 
     "id": 6, 
     "description": "Project B", 
     "updated_at": "2017-07-13T09:30:51+02:00", 
     "created_at": "2017-07-13T09:30:51+02:00" 
    } 
] 

我有以下的JSON模式的任務,這是我無法改變:

[ 
    { 
     "id": 3, 
     "project": { 
      "id": 3, 
      "description": "Project A" 
     }, 
     "description": "Task 1" 
    }, 
    { 
     "id": 6, 
     "project": { 
      "id": 3, 
      "description": "Project A" 
     }, 
     "description": "Task 2" 
    }, 
    { 
     "id": 9, 
     "project": { 
      "id": 3, 
      "description": "Project A" 
     }, 
     "description": "Task 3" 
    }, 
    { 
     "id": 12, 
     "project": { 
      "id": 6, 
      "description": "Project B" 
     }, 
     "description": "Task 4" 
    } 
] 

我有以下2種型號:

using SQLite.Net.Attributes; 
using SQLiteNetExtensions.Attributes; 

namespace BettyMultiModel.Resources.Model 
{ 
    public class Models 
    { 

    } 

    class Project : Models 
    { 

     public int Id { get; set; } 
     public string Description { get; set; } 

    } 

    class Task : Models 
    { 

     public int Id { get; set; } 
     public string Description { get; set; } 

    } 
} 

我用這個方法來獲取JSON到SQLite數據庫:

// Insert Records of type TType into database. 
private async Task<string> InsertRecords<TType>(HttpResponseMessage response) 
     where TType : Models 
{ 
    try 
    { 
     DataBase db = new DataBase(); 

     string responseString = await response.Content.ReadAsStringAsync(); 
     var responseBody = JsonConvert.DeserializeObject<List<TType>>(responseString); 


     foreach (TType item in responseBody) 
     { 
      bool resultInsert = db.Insert(item); 
     } 

     return ResponseToMessage(response, "Insert Records"); 
    } 
    catch (Exception ex) 
    { 
     Log.Info("DeserializeObject", ex.Message); 
     throw; 
    }    

} 

時,我只希望有Id和兩種模型的說明性質這一切正常。但我也想在Task模型中存儲項目模型和任務模型/項目ID之間的關係。

當我在http://json2csharp.com/解析JSON與任務,我得到了模型的以下建議:

public class Project 
{ 
    public int id { get; set; } 
    public string description { get; set; } 
} 

public class RootObject // Which is Task 
{ 
    public int id { get; set; } 
    public Project project { get; set; } // <-------- Extra property 
    public string description { get; set; } 
} 

使用模型這樣的 - 與RootObject更名爲任務 - 在一個異常的結果: NotSupportedException異常:不知道BettyMultiModel.Resources.Model.Project

所以我改變了類:

using SQLite.Net.Attributes; 
using SQLiteNetExtensions.Attributes; 

namespace BettyMultiModel.Resources.Model 
{ 
    public class Models 
    { 

    } 

    class Project : Models 
    { 

     [PrimaryKey] 
     public int Id { get; set; } 
     public string Description { get; set; } 

    } 

    class Task : Models 
    { 

     [PrimaryKey] 
     public int Id { get; set; } 
     public string Description { get; set; } 

     [OneToMany] 
     public Project project { get; set; } 

    } 
} 

異常不再被拋出,但是當我查看db文件時,仍然只有Id和Description列,並且沒有提及這兩個模型之間的關係。

我在這裏錯過了什麼?

編輯:創建表

public void ClearTable<TType>() 
     where TType : Models 
{ 
    try 
    { 
     Log.Info("Folder DB: ", dbPath); 

     using (var connection = new SQLiteConnection(platform, dbPath)) 
     { 
      connection.DropTable<TType>(); 
      connection.CreateTable<TType>(); 
     } 
    } 
    catch (SQLiteException ex) 
    { 
     Log.Info("SQLiteEx", ex.Message); 
    } 

} 

編輯添加方法:幾乎沒有...

我還做了一個小錯誤,一個項目有許多任務,所以該屬性應該是[ManyToOne]。 db中的表現在看起來不錯。項目ID只是沒有插入任務模型中的ProjectId列中。每行都有值0.我想我需要弄清楚如何將嵌套的項目對象的id映射到類Task的ProjectId屬性。

我試過使用這樣的Newtonsoft.Json命名空間,它在Task模型中插入1行,然後由於記錄ID的唯一性而開始拋出錯誤。JsonProperty( 「ID」)將其標識爲任務的ID,而不是項目:

[JsonProperty("id"), ForeignKey(typeof(Project))] 
public int ProjectId { get; set; } 

這些機型現在:

class Project : Models 
{ 

    [PrimaryKey] 
    public int Id { get; set; } 

    public string Description { get; set; } 

} 

class Task : Models 
{ 

    [PrimaryKey] 
    public int Id { get; set; } 

    public string Description { get; set; } 

    [ForeignKey(typeof(Project))] 
    public int ProjectId { get; set; } 

    [ManyToOne] 
    public Project Project { get; set; } 

} 
+0

是怎樣的數據庫結構生成?我認爲你在某處調用了「CreateTable(type)」?如果你這樣做,也許你錯過了一個CreateTable(typeof(Project)); – TomTom

+0

@TomTom:的確如此。我在底部添加了該方法。 – Robert

回答

1

假設,在你的問題你使用Twin Coders SQLite-Net-Extensions軟件包我認爲在定義模型方面存在錯誤。

如果你看一下許多在鏈接頁面到位桶一個部分,你需要在除了ManyToOne屬性來定義一個ForeignKey屬性。這是他們的例子(注意在Person類總線和BusId屬性):

public class Bus 
{ 
    [PrimaryKey, AutoIncrement] 
    public int Id { get; set; } 

    public string PlateNumber { get; set; } 
} 

public class Person 
{ 
    [PrimaryKey, AutoIncrement] 
    public int Id { get; set; } 

    public string Name { get; set; } 

    [ForeignKey(typeof(Bus))] 
    public int BusId { get; set; } 

    [ManyToOne] 
    public Bus Bus { get; set; } 
} 

與您的代碼,我相信所有你需要做的就是用下面的模型:

class Project : Models 
{ 
    [PrimaryKey] 
    public int Id { get; set; } 

    public string Description { get; set; } 

    // The id of the task used in the relationship (this gets stored in the DB) 
    [ForeignKey(typeof(Task))] 
    public int TaskId { get; set; } 

    // Meaning you have many projects to one task 
    [ManyToOne] 
    public Task Task { get; set; } 
} 

class Task : Models 
{ 
    [PrimaryKey] 
    public int Id { get; set; } 

    public string Description { get; set; } 
} 
+0

這非常接近解決方案。我與ManyToOne犯了一個小錯誤,這必須是OneToMany。我希望在上一期中看到我的文章底部的更新。謝謝! – Robert

+0

沒問題。當然,屬性應該是JsonProperty(「projectId」)? – TomTom

+0

另外,您更新的模型[ManyToOne]表示您對每個項目都有許多任務。這是期望的嗎?如果你想爲每個任務設置很多項目,我會像在答案中一樣將外鍵移動到Project。 – TomTom