【问题标题】:Entity Framework 5 : One to Many with foreignKey Updated/Added/Deleted实体框架 5:一对多,foreignKey 更新/添加/删除
【发布时间】:2016-07-13 12:24:58
【问题描述】:

当我更新我的会员时,我也想更新他的 BankCheck。

这是我的数据库:

  • 可以添加、更新或删除我的银行支票。
  • 我的会员只能更新(姓名、姓氏...)

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

我点击我的按钮来添加/编辑/删除他的银行支票,我可以编辑第一张银行支票。

我删除最后一个 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);
    }
}  

但我有这个错误:

发生了参照完整性约束冲突:定义参照约束的属性值在关系中的主体对象和依赖对象之间不一致。

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

谢谢。

我的代码:

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

【问题讨论】:

    标签: c# mysql wpf entity-framework-5


    【解决方案1】:

    如我所见,您只更新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 将自动跟踪已修改的实体并为其设置适当的状态。但正如我从您的问题中看到的那样,它已为您关闭,因此您必须手动设置要添加/更新/删除的每个对象的状态。

    【讨论】:

    • 是的,我已经找到了这些链接......这就是我所做的。
    • 那么您是否尝试过那里提到的所有方法但对您没有帮助?从您的描述中,我看不出您的问题与这些链接中提到的问题之间有任何重大区别。我没有看到完整的代码,所以当您有更多信息时,您可能能够调查有什么区别并尝试使其与这些示例中的工作相同。
    • 还要检查您是否在两侧都将实体标记为已修改(当您更新 Customer 的导航属性时,您也应该更新相应的 BankCheck)。检查此链接:stackoverflow.com/a/16128818/3731444
    • 如我所见,您只更新Member,而不是所有修改后的BankAccounts。您正在从两侧更新实体的导航属性,但仅在一侧的实体上调用 SaveChanges()。所以你的Member 开始引用另一个BankAccount,而你的BankAccounts 仍然引用旧的Member。您需要将所有适当的BankAccounts 与修改后的Member 一起标记为已修改,然后调用SaveChanges(),以便保存所有内容。
    • 好的,我已经更新了我的原始代码(在我的 foreach bankCheck 中)。我将已添加状态进行测试,它可以工作,但 EF 创建了另一个成员。如果你愿意,我可以聊天。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    相关资源
    最近更新 更多