2017-08-14 87 views
0

我有一個DataGridView和DataGridView的DataSource是一個BindingList我從實體框架(V6)通過context.Person.Local.ToBindingList()。 當我將DataSource設置爲此BindingList後,我放棄了上下文,因爲我認爲保持上下文開放將是不好的做法。因此,如果我想添加一個新行,我會點擊「添加」按鈕,隨着BindingNavigator隨我將「人員」對象數據源拖到我的Windows窗體時創建。 每次我點擊「添加」按鈕,我都會得到一個異常,告訴我已經處理了上下文。 使用DataGridView時,我是否需要始終保持上下文打開狀態?哦,並且:DataSource可能會在運行時根據列表框項的選擇而改變。另外,當上下文已經被處理並且我從DataGridView中編輯了一行時,我怎麼能找出(經過多次更改後)哪一行發生了變化? 我試圖做的:保持DbContext打開DataGridView

foreach(DataGridViewRow row in peopleDataGridView.Rows) 
{ 
    People item = (People)row.DataBoundItem; 
    if (item != null) 
    { 
     db.People.Attach(item); 
    } 
} 
db.SaveChanges(); 

...但調用SaveChanges()不承認任何變化。但是,如果我強制每個附加項目處於「修改」狀態,它就會起作用。但我不想將100個項目更改爲「修改」,如果只有一個實際修改。

任何想法?

編輯1 哦,所以我改變了我的代碼,以保持上下文打開所有的時間(或至少只要形式被顯示)。 現在,我遇到了一個不同的問題(有些人可能有很多工作):

private void listBox1_SelectedValueChanged(object sender, EventArgs e) 
{ 
    People p = (People)listBox1.SelectedItem; 
    if(p != null) 
    { 
     //jobBindingSource.Clear(); this caused another error at runtime... 
     db.Entry(p).Collection(b => b.Job).Load(); 
     jobBindingSource.DataSource = db.Job.Local.ToBindingList(); 
    } 
} 

綁定到該jobBindingSource實例DataGridView中顯示了一個人的正確工作,但除了從該職位先前選擇的人。我嘗試了Clear()條目,但是如果我這樣做並且兩次點擊同一個人,那麼datagridview開始有時根本不顯示任何條目。一個奇怪的行爲。 我現在做錯了什麼?

編輯2 好的...我自己找到了解決方案。但我拒絕接受,這是做了正確的方式:

private void listBox1_SelectedValueChanged(object sender, EventArgs e) 
{ 
    People p = (People)listBox1.SelectedItem; 
    if(p != null) 
    { 
     db.Dispose(); 
     db = new PeopleJobsEntities(); 
     db.People.Attach(p); 
     db.Entry(p).Collection(person => person.Job).Load(); 
     jobBindingSource.DataSource = db.Job.Local.ToBindingList(); 
    } 
} 

只有當我處理的情況下,重新打開它,整個事情的作品。原因是,如果我清除本地緩存(db.Job.Local),即使使用Load()方法,它的條目也不會被重新加載。有沒有辦法強制重新加載實體?

+0

爲什麼不在任何行被編輯或更改後執行此過程否則您需要檢查所有datagr逐行查看idview查看其中哪些已更改 – hasan

+0

此答案可能會幫助您https://stackoverflow.com/a/11520100/8175473 – hasan

+0

@hsnbl我沒有考慮這一點,因爲我希望EF會爲我自動執行此操作。但是隻有當我保持上下文打開的時候,這個自動化才能工作:-( – AudioGuy

回答

0

雖然我儘量不保留的DbContext開放的很長一段時間,你不要」數據網格沒有多少選擇。我將網格的DataSource屬性設置爲IQueryable<T>,然後所有編輯,刪除和添加由網格和上下文本身處理。只要您想保留更改,您只需撥打dbContext.SubmitChanges()即可。通過保存RowLeaveRowValidated事件,您可以保存每次用戶離開一行。或者,您可以在關閉表格時保存。但也請確保在關閉表格時致電dbContext.Dispose()

要找出哪些行改變你可以查看由執行以下操作返回ChangeSet

var changes = dbContext.GetChangeSet(); 
dbContext.SubmitChanges(); 
+0

感謝@ jaredbaszler爲您的答案。但是,這有點讓我擔心:如果我有一個使用DataGridView的軟件,並且如果該軟件使用它一個永久開放的窗口(也就是說它位於軟件的主屏幕上),那麼這個軟件將會是'壞'的? – AudioGuy

+0

只要你在完成它的時候處理DBContext就不會被認爲是壞的。 – jaredbaszler

0
  • 請確定您的物品是否爲空。

  • 檢查您的連接字符串。

而且,試試這個:

db.People.Add(item); 

相反的:

db.People.Attach(item); 
0

好,感謝@jaredbaszler我想出了這個解決方案,爲我工作得很好。 我決定讓DbContext始終保持活躍狀態​​。爲了清除本地緩存,我將每個實體都放在一個循環中。我認爲這是一個非常令人厭惡的做法。有必須是一個更好的辦法...

這是我有:

PeopleJobsEntities db; 

public FormTest() 
{ 
    InitializeComponent(); 
    db = new PeopleJobsEntities(); 
    db.Database.Log = Console.Write; 
    db.People.Load(); 
    List<People> peoplelist = db.People.Local.ToList(); 
    listBox1.DataSource = peoplelist; 
} 

private void FormTest_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    if (db != null) 
     db.Dispose(); 

} 

private void listBox1_SelectedValueChanged(object sender, EventArgs e) 
{ 
    People p = (People)listBox1.SelectedItem; 
    if(p != null) 
    { 
     List<Job> oldlist = db.Job.Local.ToList(); 
     foreach (Job j in oldlist) 
     { 
      db.Entry(j).State = EntityState.Detached; 
     } 
     db.Entry(p).Collection(b => b.Job).Load(); 
     jobBindingSource.DataSource = db.Job.Local.ToBindingList(); 
    } 
} 

private void jobBindingNavigatorSaveItem_Click(object sender, EventArgs e) 
{ 
    foreach(DataGridViewRow row in jobDataGridView.Rows) 
    { 
     if(row != null && row.DataBoundItem != null) 
     { 
      Job j = (Job)row.DataBoundItem; 
      if(db.Entry(j).State == EntityState.Added) 
      { 
       if(j.People.Count == 0) 
       { 
        People people = (People)listBox1.SelectedItem; 
        if (people != null) 
         j.People.Add(people); 
       } 
      } 
     } 
    } 
    db.SaveChanges(); 
} 
  • 編輯條目工作
  • 添加新條目作品
  • 刪除條目工作