添加新的多对多对象后,旧记录发生变化(不受欢迎)

Old records change (undesirably) after adding new Many-to-Many object

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

也删除了一些之前的中间表记录(参考:图2)。

代码如下:

型号:

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);
                });
    }
}

如何在不影响(不利地)以前的记录的情况下添加引用者?

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

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

public async Task SaveQuoter() {

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

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

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

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

Reference