SQLite Xamarin中的一对多关系

时间:2016-03-13 20:12:46

标签: c# sqlite xamarin sqlite-net sqlite-net-extensions

我正在构建一个Xamarin移动应用程序,我有一套我从休息api获得的产品。每个产品可以有n个图像。我使用SQLite-Net Extensions设置了表的关系。但是,当我将值插入数据库时​​,Images字段在Product表中具有空值,而Image表在空中。

我的模特

    public class Product
{
    [SQLite.Net.Attributes.PrimaryKeyAttribute]
    public int ID { get; set; }
    public string Name { get; set; }
    [OneToMany] 
    public List<Image> Images { get; set; }
}

public class Image
{
    [SQLite.Net.Attributes.PrimaryKeyAttribute, SQLite.Net.Attributes.AutoIncrement]
    public int ID { get; set; }
    [ForeignKey(typeof(Product))]     // Specify the foreign key
    public int ProductID { get; set; }
    public string Link { get; set; }
}

我用来插入值的代码。

var db = new SQLiteConnection(new SQLitePlatformAndroid(), path);
var info = db.GetTableInfo("ProductDB");
db.CreateTable<ProductDB>();
db.CreateTable<ImageDB>();
db.DeleteAll<ProductDB>();
db.DeleteAll<ImageDB>();
db.InsertAllWithChildren(data);
db.UpdateAll(data);

这就是我如何将json反序列化为对象

public async Task<List<ProductDB>> GetAllProducts()
    {
        var httpClient = GetHttpClient();

        var response = await httpClient.GetAsync(ServiceEndPoints.GetFilmsUri).ConfigureAwait(false);

        if (response.IsSuccessStatusCode)
        {
            var content = response.Content;

            string jsonString = await content.ReadAsStringAsync().ConfigureAwait(false);

            return JsonConvert.DeserializeObject<List<ProductDB>>(jsonString);
        }
        return null;
    }

如果有人可以帮助我找出我做错了什么,那将会很棒。

2 个答案:

答案 0 :(得分:1)

db.InsertAllWithChildren(data);
db.UpdateAll(data); 

使用子值插入值,然后使用相同的值进行更新,并使用null更新ProductID值,因为它们应由数据库设置。如果要更新数据,则应为每个要插入的项设置外键,或者使用UpdateWithChildren

答案 1 :(得分:1)

我猜dataList<Product>。在这种情况下,您只是在数据库中插入产品而没有插入图像。

这里有两个选项:手动插入图像或使用递归操作。

要手动插入图片,只需在>插入产品之前使用所有图片调用InsertAll方法:

List<Image> images = data.SelectMany(p => p.Images ?? new List<Image>());
conn.InsertAll(images);
conn.InsertAllWithChildren(data);

使用递归操作更简单,但需要进行少量配置。通过设置关系属性的CascadeOperation属性启用级联操作:

[OneToMany(CascadeOperations = CascadeOperation.All)] 
public List<Image> Images { get; set; }

然后,您可以将recursive方法的-WithChildren参数设置为true以执行级联操作:

conn.InsertAllWithChildren(data, recursive: true);