Entity Framework 5 : 一对多外键 Updated/Added/Deleted

Entity Framework 5 : One to Many with foreignKey Updated/Added/Deleted

当我更新我的会员时,我也想更新他的银行支票。

这是我的数据库:

我在我的数据网格中选择我的成员,然后select编辑,我的 wpf 应用程序切换到另一个页面并用文本框等显示我的成员

我点击我的按钮 add/edit/delete 他的 bankCheck,我可以编辑第一个 bankCheck。

我删除了最后一个 bankCheck 并添加了另一个(例如)。

我按确定,然后单击 "Valid my Edit"。

我的程序用他的 bankCheck 重新创建了一个新会员,我做了这个:

private void EditMember(Member updatedMember)
{
    try
    {  
        using (var context = new KravMagaEntities())
        {
            context.Member.Attach(updatedMember);
            context.Entry(updatedMember).State = EntityState.Modified;
            context.SaveChanges();
        }

        ResetAllControls();
        States.EnumToText(States.StatesEnum.UpdatingSuccess);

        Application.Current.Dispatcher.Invoke(() =>
        {
            _managementService.IsVisibleAddTab(true);
            _managementService.IsVisibleEditTab(false);
        });
    }
    catch (Exception exception)
    {
        States.EnumToText(States.StatesEnum.Error, exception);
    }
}  

但是我有这个错误:

A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.

我不知道如何解决这个错误。

谢谢。

我的代码:

private void OnEditMemberBtnClicked(object sender, RoutedEventArgs e)
{
    try
    {
        var isValidateCertificat = IsValidDate(BirthDateTxt);
        var isValidateBirth = IsValidDate(CertificateDateTxt);
        var isValidateAutorisation = IsValidDate(AutorizationDateTxt);
        var isValidateReglement = IsValidDate(RuleDateTxt);

        if (isValidateBirth && isValidateCertificat && isValidateAutorisation && isValidateReglement)
        {
            States.EnumToText(States.StatesEnum.Updating);

            var typePaiement = BankCheckRadio.IsChecked.Value;
            var typePaiementText = typePaiement ? "Chèque" : "Espèce";

            var doctor = "";
            var dateCertificate = "";

            if (BankCheckRadio.IsChecked.Value)
            {
                doctor = DoctorTxt.Text;
                dateCertificate = CertificateDateTxt.Text;
            }

            var editedMember = new Member
            {
                id_Member = _idForEdit,
                name_Member = UppercaseChar(NameTxt.Text),
                surname_Member = UppercaseChar(SurnameTxt.Text),
                birthDate_Member = BirthDateTxt.Text,
                autorizationDate_Member = AutorizationDateTxt.Text,
                address_Member = UppercaseChar(AddressTxt.Text),
                postalCode_Member = PostalCodeTxt.Text,
                country_Member = UppercaseChar(CountryTxt.Text),
                fixPhone_Member = FixPhoneTxt.Text,
                mobilePhone_Member = MobilePhoneTxt.Text,
                mail_Member = MailTxt.Text,
                beginDate_Member = BeginDateCombo.Text,
                ruleDate_Member = RuleDateTxt.Text,
                subscription_Member = SubscriptionCombo.Text,
                typePaiement_Member = typePaiement,
                typePaiementText_Member = typePaiementText,
                federationNumero_Member = FederationNumeroTxt.Text.ToUpper(),
                level_Member = LevelCombo.Text,
                certificate_Member = CertificateCheckbox.IsChecked.Value,
                doctor_Member = UppercaseChar(doctor),
                certificateDate_Member = dateCertificate,
                problem_Member = UppercaseChar(ProblemTxt.Text, true),
                emergencyName_Member = UppercaseChar(EmergencyNameTxt.Text),
                emergencyPhone_Member = EmergencyPhoneTxt.Text,
                BankCheck = _bankChecks
            };

             if (_bankChecks != null)
                { 
                    using (var context = new KravMagaEntities())
                    {
                        foreach (var bankCheck in _bankChecks)
                        {
                            bankCheck.idMember_BankCheck = editedMember.id_Member;
                            context.Entry(bankCheck).State = EntityState.Added;
                        }
                        context.SaveChanges();
                    }
                }

            new Task(() => EditMember(editedMember)).Start();
        }
    }
    catch (Exception exception)
    {
        States.EnumToText(States.StatesEnum.Error, exception);
    }
}

据我所知,您只更新了 Member,而不是所有修改后的 BankAccounts。您正在从两侧更新实体的导航 属性,但仅在一侧的实体上调用 SaveChanges()。所以你的 Member 开始引用另一个 BankAccount 而你的 BankAccounts 仍然引用旧的 Member。您需要将所有适当的 BankAccounts 标记为已修改以及修改后的 Member 在同一位置,然后调用 SaveChanges() 以便保存所有内容 (来自评论).

为防止添加重复项,您可以尝试将实体的状态设置为 State.Modified 而不是 State.Added

该问题的原因是您仅从一侧更新实体。如果您有 BankAccounts-Members 关系,那么如果您为 Member 更新导航 属性,您也应该为 BankAccount 更新导航 属性反之亦然。如果你只是更新一些 属性(Member.Name 或任何东西)你只需将这个 MemberState 设置为 State.Modified 而不会影响任何其他 MemberBankAccount

如果为您启用了实体跟踪,那么 EF 将自动跟踪已修改的实体并为它们设置适当的状态。但是正如我从您的问题中看到的那样,它已为您关闭,因此您必须手动设置每个对象的状态 add/update/delete.