无法定义这两个对象之间的关系,因为它们附加到不同的ObjectContext对象
本文关键字:对象 因为 ObjectContext 关系 两个 之间 定义 | 更新日期: 2023-09-27 18:21:57
我在SQL中有两个表。一个被称为Training
,一个被称作Consultants
。训练是像ID, Place, Time, Date
这样的两个字段,它还有ConsultantName
,它是外键,并与具有顾问名称、顾问名字等的Consultants
相连。
在保存Training期间,我首先保存Training,然后将Training值传递为varTraining。根据我在堆栈上发现的一些建议,我试图将其与上下文相匹配,但似乎不起作用:
Training Training = context.Trainings.First(p => p.TrainingID == varTraining.TrainingID);
context.Trainings.Attach(Training);
currentUczestnik.Training = Training;
这是代码:
using (var context = new EntityBazaCRM(Settings.sqlDataConnectionDetailsCRM))
{
Training Training = context.Trainings.First(p => p.TrainingID == varTraining.TrainingID);
foreach (var currentUczestnik in listaUczestnikow)
{
context.Trainings.Attach(Training);
currentUczestnik.Training = Training;
if (context.TrainingUczestnicies.Any(t => t.TrainingUczestnicy1 == currentUczestnik.TrainingUczestnicy1))
{
context.TrainingUczestnicies.Attach(currentUczestnik);
context.ObjectStateManager.ChangeObjectState(currentUczestnik, EntityState.Modified);
}
else
{
// context.Detach(currentUczestnik.Consultant);
context.Consultants.Attach(currentUczestnik.Consultant);
context.TrainingUczestnicies.AddObject(currentUczestnik);
//context.TrainingUczestnicies.Attach(
}
}
try
{
context.SaveChanges();
}
catch (Exception ex)
{
string excepion = ex.InnerException.ToString();
MessageBox.Show(excepion);
}
}
编辑:
整个故事是这样的。
这是一张顾问表。人员已加载:
using (var context = new EntityBazaCRM(Settings.sqlDataConnectionDetailsCRM)) {
IQueryable<Konsultanci> listaKonsultantow = from k in context.Konsultancis select k;
objectListViewKonsultanci.SetObjects(listaKonsultantow);
}
它们被加载到ObjectListview中。然后,当用户单击该ObjectListView时,以下顾问将被"复制"到ObjectListView参与者中。
foreach (Konsultanci konsultant in objectListViewKonsultanci.SelectedObjects) {
dodajUczestnikowSzkolen(konsultant);
}
创建一个名为SzkolenieUczestniczy(参与者)的新对象,并在其连接时为其分配顾问。还添加了一些其他属性。
private void dodajUczestnikowSzkolen(Konsultanci konsultant) {
SzkolenieUczestnicy nowyUczestnik = new SzkolenieUczestnicy();
nowyUczestnik.Konsultanci = konsultant;
//nowyUczestnik.SzkolenieUzytkownik = Settings.currentlyLoggedKonsultant.KonsultantNazwa;
nowyUczestnik.SzkolenieUzytkownikData = DateTime.Now;
//listaUczestnicy.Add(nowyUczestnik);
objectListViewUczestnicy.AddObject(nowyUczestnik);
}
现在用户保存Training(一些字段,如Date、Time、Topic已附加到currentSzkolenie(Training):
private void sqlZapiszSzkolenie() {
using (var context = new EntityBazaCRM(Settings.sqlDataConnectionDetailsCRM)) {
if (context.Szkolenies.Any(t => t.SzkolenieID == currentSzkolenie.SzkolenieID)) {
context.Szkolenies.Attach(currentSzkolenie);
context.ObjectStateManager.ChangeObjectState(currentSzkolenie, EntityState.Modified);
} else {
context.Szkolenies.AddObject(currentSzkolenie);
}
context.SaveChanges();
context.Detach(currentSzkolenie);
}
}
所以,在我保存了培训,培训现在在数据库中之后,我开始保存参与者。我取currentSzkolenie
(用于训练的全局变量)并将其作为变量传递:
private void sqlZapiszUczestnikow(ObjectListView listaUczestnikow, Szkolenie varSzkolenie) {
foreach (SzkolenieUczestnicy currentUczestnik in listaUczestnikow.Objects) {
using (var context = new EntityBazaCRM(Settings.sqlDataConnectionDetailsCRM)) {
Szkolenie szkolenie = context.Szkolenies.First(p => p.SzkolenieID == varSzkolenie.SzkolenieID);
context.Attach(szkolenie);
currentUczestnik.Szkolenie = szkolenie;
// currentUczestnik.Szkolenie.EntityKey = szkolenie.EntityKey;
if (context.SzkolenieUczestnicies.Any(t => t.SzkolenieUczestnicy1 == currentUczestnik.SzkolenieUczestnicy1)) {
context.SzkolenieUczestnicies.Attach(currentUczestnik);
context.ObjectStateManager.ChangeObjectState(currentUczestnik, EntityState.Modified);
} else {
// context.Detach(currentUczestnik.Konsultanci);
context.Konsultancis.Attach(currentUczestnik.Konsultanci);
context.SzkolenieUczestnicies.AddObject(currentUczestnik);
//context.SzkolenieUczestnicies.Attach(
}
try {
context.SaveChanges();
} catch (Exception ex) {
string excepion = ex.InnerException.ToString();
MessageBox.Show(excepion);
}
}
}
}
仅此而已。它在currentUczestnik.Szkolenie = szkolenie;
上引发错误
我用两个解决方案解决了它。
-
我已经在类的顶部声明了
private EntityBazaCRM context = new EntityBazaCRM(Settings.sqlDataConnectionDetailsCRM);
,并一直重用它,而没有将它放入using
中。多亏了这个动作,我在保存之前不必附加任何东西。我只是使用了相同的上下文,并使用currentUczestnik.Szkolenie = szkolenie;
和currentUczestnik.Konsultanci=consultants;附加了我想要的任何外键;。它保存得很好。 -
我没有像
currentUczestnik.Szkolenie = szkolenie;
那样附加整个对象,而是通过SzkolenieReference和SzkorenieID上的EntityKey添加了它。context.Attach(szkolenie); context.Szkolenies.Attach(szkolenie); currentUczestnik.SzkolenieReference.EntityKey = szkolenie.EntityKey; currentUczestnik.SzkolenieID = szkolenie.SzkolenieID;
-
解决方案3是在旧对象的基础上创建新对象。引用的Konsultanci和Szkolenia有点重新同步(我认为这实际上是从数据库中重新获取它们)。
using (var context = new EntityBazaCRM(Settings.sqlDataConnectionDetailsCRM)) { if (currentUczestnik.SzkolenieUczestnicyID == 0) { var nowy = new SzkolenieUczestnicy { Konsultanci = context.Konsultancis.First(p => p.KonsultantNazwa == currentUczestnik.Konsultanci.KonsultantNazwa), Szkolenie = context.Szkolenies.First(p => p.SzkolenieID == varSzkolenie.SzkolenieID), SzkolenieUzytkownik = currentUczestnik.SzkolenieUzytkownik, SzkolenieUzytkownikData = currentUczestnik.SzkolenieUzytkownikData, UczestnikPotwierdzilUdzial = currentUczestnik.UczestnikPotwierdzilUdzial, UczestnikPrzybyl = currentUczestnik.UczestnikPrzybyl }; context.SzkolenieUczestnicies.AddObject(nowy); context.SaveChanges(); listaDoPodmiany.Add(nowy);
-
第4个解决方案是我最终使用的。基本上,它将所有引用的对象置空(首先将它们临时保存到对象中),然后在保存之前只使用它们的ID值。然后在重新附加保存对象之后。
foreach (SzkolenieUczestnicy uczestnik in listaUczestnikow.Objects) { using (var context = new EntityBazaCRM(Settings.sqlDataConnectionDetailsCRM)) { if (uczestnik.SzkolenieUczestnicyID == 0) { // add new object var konsultant = uczestnik.Konsultanci; uczestnik.Konsultanci = null; // null attached object and reuse it's ID later on for SAVE purposes uczestnik.KonsultantNazwa = konsultant.KonsultantNazwa; uczestnik.Szkolenie = null; // null attached object and reuse it's ID later on for SAVE purposes uczestnik.SzkolenieID = szkolenie.SzkolenieID; context.SzkolenieUczestnicies.AddObject(uczestnik); context.SaveChanges(); context.Detach(uczestnik); // detatch to prevent Context problems uczestnik.Szkolenie = szkolenie;// reassign for use in ObjectListView uczestnik.Konsultanci = konsultant; // reassign for use in ObjectListView } else { // modify exisinng object context.SzkolenieUczestnicies.Attach(uczestnik); //context.ObjectStateManager.ChangeObjectState(uczestnik, EntityState.Modified); context.SaveChanges(); } } }