添加新的多对多对象后,旧记录会发生变化(不合需要)

时间:2016-10-16 22:18:19

标签: sqlite-net-extensions

当我添加新的“多对多”对象时,旧记录中的某些关系字段值将设置为null或0(参考:图像1)。

Quotes Table

还会删除一些先前的中间表记录(参考:图像2)。

QuoterProfession intermediate table

以下是代码:

型号:

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


[Table(nameof(Quoter))]
public class Quoter : ModelBase
{
    [Unique, MaxLength(30)]
        public string Name {set; get;}

        [ManyToMany(typeof(QuoterProfession), CascadeOperations = CascadeOperation.CascadeInsert | CascadeOperation.CascadeRead)]
        public List<Profession> Professions {set; get;}

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


[Table(nameof(Quote))]
public class Quote : ModelBase
{
        public string Statement {set; get;}

        [ForeignKey(typeof(Quoter))]
        public int QuoterId { get; set; }
        [ManyToOne(CascadeOperations = CascadeOperation.CascadeInsert | CascadeOperation.CascadeRead)]
        public Quoter Quoter {set; get;}

        [ForeignKey(typeof(Profession))]
        public int ProfessionId { get; set; }
        [ManyToOne(CascadeOperations = CascadeOperation.CascadeInsert | CascadeOperation.CascadeRead)]
        public Profession Profession {set; get;}
}


[Table(nameof(Profession))]
public class Profession : ModelBase
{
        [Unique, MaxLength(20)]
        public string Name {set; get;}

        [ManyToMany(typeof(QuoterProfession), CascadeOperations = CascadeOperation.CascadeInsert | CascadeOperation.CascadeRead)]
        public List<Quoter> Quoters {set; get;}

        [OneToMany(CascadeOperations = CascadeOperation.CascadeInsert | CascadeOperation.CascadeRead)]
        public List<Quote> Quotes {set; get;}
}


[Table(nameof(QuoterProfession))]
class QuoterProfession : ModelBase
{
        [ForeignKey(typeof(Quoter))]
        public int QuoterId { get; set; }
        [ForeignKey(typeof(Profession))]
        public int ProfessionId { get; set; }
 }

视图模型:

public class AddQuoterPageVm   
{
    public Quoter Quoter { get; set; }

        public List<Profession> Professions { get; set; }

        public ObservableCollection<Profession> QuoterProfessions { get; set; }
        public Profession QuoterProfession { get; set; }

        public Profession QuoteProfession { get; set; }

        public Quote Quote { get; set; }

        public ObservableCollection<Quote> Quotes { get; set; }

    public void SaveQuoter()   // Add a new Quoter with all his properties & Save
    {
        Quoter = new Quoter {Name = "QuoterN"};
        asyncConnection.InsertWithChildrenAsync(Quoter).Wait();   // Adds a new Quoter to database


        AddProfessions();   // Add profession to database
        Professions = asyncConnection.GetAllWithChildrenAsync<Profession>().Result;

        // Add QuoterN's profession
    QuoterProfessions = new ObservableCollection<Profession>{ Professions[0], Professions[1] };
        Quoter.Professions = new List<Profession>(QuoterProfessions);

        Quotes = new ObservableCollection<Quote> 
        {
            new Quote {Statement = "q1 q1", Profession = Professions[0]},
            new Quote {Statement = "q1 q2", Profession = Professions[1]}
        };
    Quoter.Quotes = new List<Quote>(Quotes);   // Add QuoterN's quotes
            Quotes = null;  

    // Update QuoterN in database after adding additional properties
        asyncConnection.InsertOrReplaceWithChildrenAsync(Quoter, true);   
    }

    private void AddProfessions()   // Adds professions to database
    {
        asyncConnection.GetAllWithChildrenAsync()
                    .ContinueWith(professionListTask =>
                {
                    if (professionListTask.Result.Any()) return;

                    var professions = new List<Profession>
                    {
                        new Profession {Name = "Profession1"},
                        new Profession {Name = "Profession2"},
                        new Profession {Name = "Profession3"},
                        new Profession {Name = "Profession4"},
                        new Profession {Name = "Profession5"},
                        new Profession {Name = "Profession6"},
                        new Profession {Name = "Profession7"}
                    };

                    asyncConnection.InsertAllWithChildrenAsync(professions);
                });
    }
}

如何在不影响(不合需要)以前的记录的情况下添加Quoter?

2 个答案:

答案 0 :(得分:0)

可能在两端递归所有关系都会导致问题,因为您只设置其中一个而另一端可能不一致。由于您没有使用递归插入操作,我建议您从所有关系中删除CascadeOperation.CascadeInsert,或将反向关系标记为ReadOnly

我不确定等待这样的异步操作是否会导致问题,所以我也试着修复它。尝试等待异步操作并返回Task而不是void来返回结果任务:

public async Task SaveQuoter() {

    Quoter = new Quoter {Name = "QuoterN"};
    await asyncConnection.InsertWithChildrenAsync(Quoter);
    await AddProfessions();
    Professions = await asyncConnection.GetAllWithChildrenAsync<Profession>();
    ...
}

您可以查看来源中包含的IntegrationTests project中的示例代码。

答案 1 :(得分:0)

我使用asyncConnection.UpdateWithChildren(Quoter)更新了Quoter。使用此旧记录后不会被删除。

之前我使用的是asyncConnection.InsertOrReplaceWithChildrenAsync(Quoter, true)

Reference