2015-12-25 127 views
0

我嘗試創建數據庫應用程序並實現MVP模式。 我正在使用EF + CodeFirst。 有View,PresenterModel如何保存dataGridView更改的數據?

查看有dataGridViewSetData()方法。

public void SetData(IEnumerable<Goods> items) 
{ 
    dataGridView1.DataSource = items.ToList(); 
} 

Presenter從Model中檢索數據並調用View的SetData()。

internal void Select() 
{ 
    var data = _modelGoods.Select(); 
    _view.SetData(data); 
} 

但是,如何保存更改的單元格數據?

+1

如果您正在使用斷開機構工作,你應該跟蹤實體的變化。你的一些實體被添加,​​其中一些被更改,其中一些被刪除。並且您想要插入這些添加的實體並更新這些更改的實體並從上下文中刪除這些刪除的實體。 –

+0

@RezaAghaei它被稱爲斷開情景? –

+0

如果使用服務獲取數據,並且無法訪問從其獲取數據的上下文,則會斷開連接。例如,在連接場景中,您可以在表單中創建上下文實例,並獲取數據和操作數據,然後將更改保存到上下文中。 –

回答

1

通常,要使用EF更新記錄,請首先閱讀實體對象,然後使用新值更新屬性值並將其保存。

就是這樣。

var idOfRecord=12; 
using(var yourDbContext=new YourDbContext()) 
{ 
    var good=yourDbContext.Goods.FirstOrDefault(s=>s.Id==idOfRecord); 
    if(good!=null) 
    { 
    good.Name = "New name read from UI"; //Updating the Name property value 
    yourDbContext.Entry(good).State = EntityState.Modified; 
    yourDbContext.SaveChanges(); 
    } 
} 

假設YourDbContext是你DbContext類的名稱。根據需要更新屬性/類名稱以匹配您的用例。

+0

我如何知道哪個單元格已被更改 - 名稱或其他內容? –

+0

對不起!我不確定。不是一個winform專家。但我想你應該能夠將一些唯一的ID傳回給你的代碼來跟蹤它。我的答案是解釋如何在EF中更新數據。 – Shyju

2

如果您使用的是連接實體,作業很簡單,您可以在上下文中加載數據,然後將數據綁定到網格並操作數據,最後調用SaveChanges加載數據的上下文,將更改應用於數據庫。

如果您使用的是斷開的實體,則應該跟蹤實體更改。你的一些實體被添加,​​其中一些被更改,其中一些被刪除。並且您想要插入這些添加的實體並更新這些更改的實體並從上下文中刪除這些刪除的實體。爲此,您可以繼承BindigList<T>ObservableCOllection<T>或使用BindingSource並監聽列表更改事件並跟蹤更改並將更改存儲在3個分開的列表中(添加,更改,刪除),然後將這些列表傳遞給服務器以應用更改。

樣品爲關聯單位:

SampleDbContext db; 
private void Form1_Load(object sender, EventArgs e) 
{ 
    db = new SampleDbContext(); 
    db.Products.Load(); 
    this.productDataGridView.DataSource = db.Products.Local.ToBindingList(); 
} 
private void SaveButton_Click(object sender, EventArgs e) 
{ 
    this.productDataGridView.EndEdit(); 
    db.SaveChanges(); 
} 

樣品爲斷開實體:

我想你已經使用BindingSourceBindingList<T>ObservableCollection<T>甚至使用DataGridView事件或別的東西修訂。現在,你應該已經添加,編輯和刪除的實體,您可以將它們傳遞到你的服務器代碼將更改應用這種方式:

public void SaveChanges(List<Product> added, List<Product> edited, List<Product> deleted) 
{ 
    using (var db = new SampleDbContext()) 
    { 
     foreach (var entity in deleted) 
     { 
      if (edited.Contains(entity)) 
       edited.Remove(entity); 

      if (added.Contains(entity)) 
       added.Remove(entity); 
      else 
       db.Entry(entity).State = EntityState.Deleted; 
     } 

     foreach (var entity in added) 
     { 
      if (edited.Contains(entity)) 
       edited.Remove(entity); 
      db.Entry(entity).State = EntityState.Added; 
     } 

     foreach (var entity in edited) 
      db.Entry(entity).State = EntityState.Modified; 

     db.SaveChanges(); 
    } 
} 
+0

斷開的方法看起來非常可怕。但在[this](http://www.entityframeworktutorial.net/EntityFramework5/attach-disconnected-entity-graph.aspx)教程中,沒有關於跟蹤更改的說明。我不知道更多關於它的地方? –

+0

我並沒有說這是一個好方法,但對於可能正常工作的應用程序來說,這是一種非常簡單的方法,而且我不確定您是否正在斷開連接或正在連接。此外,我認爲該示例是如何工作連接的一個很好的示例,並且對未來的讀者會有所幫助:) –

+0

還添加了如何保存斷開連接的數據的示例。 –

0

我不是MVP模式的專家,如果基於實例查看了解模型,
那麼你可以使用DataGridView.CellEndEdit事件處理

private void dgvtest1_CellEndEdit(Object sender, DataGridViewCellEventArgs e) 
{ 
    if(e.RowIndex < 0) 
     return; 
    if(e.ColumnIndex < 0) 
     return; 
    DataGridView dgv = (DataGridView)sender; 
    DataGridViewRow row = dgv.Rows(e.RowIndex); 
    Good model = row.DataBoundItem as Good 
    if(model == null) 
     return; 
    //Then decide which property was changed and update it 
    String boundPropertyName= dgv.Columns(e.ColumnIndex).DataPropertyName; 
    if(boundPropertyName.Equals(nameOf(model.SomeProperty)) == true) 
    { 
     //Update value 
     return; 
    } 
    //.. other columns 
} 
相關問題