2012-01-31 83 views
0

我在SQL中有2個表。一個叫做Training,另一個叫Consultants。培訓是情侶喜歡ID, Place, Time, Date領域,它也有ConsultantName這是外鍵,並與具有ConsultantName,ConsultantFirstName等無法定義兩個對象之間的關係,因爲它們連接到不同的ObjectContext對象

Consultants在節省訓練我先救訓練,然後再通過訓練值varTraining連接。我試圖把它attatch上下文按照一些建議,我在棧上找到,但它似乎不工作:

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

現在,用戶可以節省培訓(如日期某些領域,時間,主題被裝到currentSzkolenie(培訓):

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;

+0

讀例外我的猜測是,在'對象listaUczestnikow'已經連接到另一個環境。那可能嗎?你從哪裏得到這份清單? – Slauma 2012-01-31 17:12:54

+0

錯誤出現在currentUczestnik.Training = Training;而不是在listaUczestnikow。 ListaUczestnikow是簡單的List <>,它與任何已經在數據庫中的顧問都沒有關聯,這些顧問都在數據庫中,我希望他們被分配到Training。 – MadBoy 2012-01-31 17:14:32

+0

是的,但'currentUczestnik'是列表中的一個對象,這就是我的意思。 '顧問'已經在數據庫中?你是否使用另一個尚未處理的上下文從數據庫加載它們? – Slauma 2012-01-31 17:18:52

回答

1

我解決了它與2解決方案。

  1. 我已經宣佈對班裏的第一名private EntityBazaCRM context = new EntityBazaCRM(Settings.sqlDataConnectionDetailsCRM);,並沒有把它變成using重用這一切的時候。由於這一行動,我不必在儲蓄之前附加任何東西。我只是使用相同的上下文,並使用currentUczestnik.Szkolenie = szkolenie;和currentUczestnik.Konsultanci = consultants;來附加我想要的任何外鍵。它保存沒有問題。

  2. 而不是附加整個對象,如currentUczestnik.Szkolenie = szkolenie;我已經通過EntityKey SzkolenieReference和SzkolenieID添加它。

    context.Attach(szkolenie); 
    context.Szkolenies.Attach(szkolenie); 
    currentUczestnik.SzkolenieReference.EntityKey = szkolenie.EntityKey; 
    currentUczestnik.SzkolenieID = szkolenie.SzkolenieID; 
    
  3. 解決方案3號是基於舊對象創建新對象。引用的Konsultanci和Szkolenia是重新同步的(我認爲它實際上是從db中重新獲得它們)。

    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. 解決方案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(); 
           } 
          } 
         } 
    
+0

我會爲解決方案1投票。我認爲在Winforms應用程序中擁有與窗口生命週期一致的上下文壽命是有好處的,尤其是您可以充分利用附加對象的更改跟蹤。 – Slauma 2012-01-31 20:49:06

+0

問題是它會在多線程等更復雜的環境中生存下來。或者當將有50個對象等 – MadBoy 2012-01-31 20:54:09

+0

我已經添加了另一種解決方案。這似乎工作得很好,可以有非全局上下文。這只是我認爲它正在重新設計Konsultanci,Szkolenie從db中引用。 – MadBoy 2012-02-01 09:47:37

相關問題