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
或任何东西)你只需将这个 Member
的 State
设置为 State.Modified
而不会影响任何其他 Member
、BankAccount
等
如果为您启用了实体跟踪,那么 EF 将自动跟踪已修改的实体并为它们设置适当的状态。但是正如我从您的问题中看到的那样,它已为您关闭,因此您必须手动设置每个对象的状态 add/update/delete.
当我更新我的会员时,我也想更新他的银行支票。
这是我的数据库:
- 可以添加、更新或删除我的银行支票。
- 我的会员只能更新(名字,姓氏...)
我在我的数据网格中选择我的成员,然后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
或任何东西)你只需将这个 Member
的 State
设置为 State.Modified
而不会影响任何其他 Member
、BankAccount
等
如果为您启用了实体跟踪,那么 EF 将自动跟踪已修改的实体并为它们设置适当的状态。但是正如我从您的问题中看到的那样,它已为您关闭,因此您必须手动设置每个对象的状态 add/update/delete.