2017-03-23 46 views
1

我在WPF應用程序中有一個主窗口和一些子窗口。使用MVVM和EF。 這裏是在層的簡要概述:從WPF中的視圖更新EF模型

  • 的MainView:在這裏我有一個GridView和保存按鈕。
  • MainViewmodel:具有ObservableCollection屬性和DelegateCommand用於保存。
  • ChildView:這裏有一個GridView和一個保存按鈕。
  • ChildViewmodel:具有ObservableCollection屬性和一個DelegateCommand用於保存。
  • DataService的:與EF模型提供Entitytype1和Entitytype2

這裏是在代碼的簡化概述(同爲子視圖):在的MainView

<Window> 
    <UserControl.DataContext> 
     <viewModel:MainViewModel/> 
    </UserControl.DataContext> 
    <Grid> 
     <GridView ItemsSource="{Binding MyEntityList}"/> 
     <Button Content="Save" Command="{Binding SaveCommand}"/> 
    </Grid> 
</Window> 

XAML

MainViewmodel中的代碼

public ObservableCollection<Entitytype1> MyEntityList { get; set; } 
private void LoadData() 
{ 
    MyEntityList = new ObservableCollection<Entitytype1>(DataServices.GetData()); 
    OnPropertyChanged("MyEntityList"); 
} 

SaveCommand = new DelegateCommand(Save); 
private void Save() 
{ 
    DataServices.SaveEntity1(); 
} 

DataServices中的代碼 我在需要的時候創建了EF模型,我猜想在應用程序的整個生命週期內都有EF掛起。這是一個壞主意嗎?

public static IList<EntityType1> GetData() 
{ 
    var list = new List<EntityType1>(); 
    using (var myEntitiesModel = new MyEntitiesModel()) 
    { 
     list = myEntitiesModel.EntityType1s.ToList(); 
    } 
    return list; 
} 

public static SaveEntity1(?) 
{ 
    ???? 
    myEntitiesModel.SaveChanges(); 
} 

所有這些工作正常,數據顯示在Mainview的網格中。

現在問題:如何將數據返回到數據庫?

當用戶更改網格中的某些內容時,它會在ObservableCollection中使用綁定更改,這很好。

但是,當用戶單擊視圖上的保存按鈕時,如何將更改返回到DataServices中的EF模型,並返回到數據庫?

我想我可以在DataServices中使用ObservableCollection並對其進行foreach並將其中的項目與EF模型中的所有項目進行比較以找到更改的項目。

但這似乎不對,什麼是更好的方法?

回答

0

我在需要的時候創建了EF模型,我想應該在應用程序的整個生命週期內都掛一個EF。這是一個壞主意嗎?

這要看情況。在企業應用程序中,客戶端應用程序不應該首先依賴實體框架。您通常會使用數據訪問層(DAL)或服務或業務層與數據庫進行通信,然後在後臺調用DAL。 EF僅存在於DAL中,客戶端應用程序僅調用服務層的某些方法來讀取和寫入數據。它不知道EF的任何內容,並且在客戶端沒有涉及DbContext

在一個小應用程序中,雖然可以在視圖模型或整個應用程序的整個生命週期中使用單個DbContext。在這種情況下,您可以創建MyEntitiesModel的單個實例,使用此上下文中的實體填充ObservableCollection<T>,然後在視圖模型的Save()方法中調用相同DbContext實例的SaveChanges()方法。

我想我可以在DataServices中創建一個方法,將ObservableCollection放入並對其進行foreach,並將其中的項目與EF模型中的所有項目進行比較以找到更改的項目。

但這似乎不對,什麼是更好的方法?

您還可以將斷開的實體附加到新的DbContext實例並設置附加實體的狀態。請參考以下博客文章以獲得更多關於此的信息:https://blog.magnusmontin.net/2013/05/30/generic-dal-using-entity-framework/

+0

因此,如果客戶端具有View(MainView)和DAL(DataServices)以及EF Model,您將如何從View查看到DAL的更改數據? –

+0

視圖模型在命令的Execute方法中調用服務層或DAL。視圖綁定到視圖模型。 – mm8

+0

正如我所建議的那樣:我想我可以在DataServices中創建一個方法,將ObservableCollection引入並對其進行foreach,並將其中的項目與EF模型中的所有項目進行比較以找到更改的項目。 –

1

我幾乎不建議不要將模型綁定到您的視圖。您應該只將ViewModel綁定到您的視圖。看看MVVM模式。

當您通過EF從數據庫加載數據時,您會看到一個項目列表。如果您遍歷此列表,您可以爲每個條目創建一個ViewModel,並且每個ViewModel可以存儲從中創建的EF模型。保存數據時,您可以遍歷ViewModel並獲取更新的EF模型。當您創建新的ViewModel(不帶EF模型)時,您可以創建一個新的EF模型。

在我看來,這是一個非常乾淨的方法,爲我工作了近10年的WPF應用程序開發。

+0

你是什麼意思'綁定模型到你查看'?我只綁定ViewModel到我的視圖。並且爲每個條目創建一個ViewModel,你的意思是什麼?它不是一個視圖 - 一個Viewmodel?像名稱約定MainView - MainViewmodel一樣。或者我錯過了什麼,你能提供一個eksample。 –

+1

但是你的屬性,例如MyEntityList包含Models而不是ViewModels。我正是這個意思。如果你的視圖的DataContext的ViewModel也使用ViewModel,會更好。 –

+0

我一直在閱讀很多關於MVVM的知識,它看起來並不是所有的固定規則。 _有人會說,直接暴露一個實體不是純MVVM,因爲實體是模型,並將模型暴露給View有點頑皮。其他人說,將數據獲取到該實體中是模型層,而實體對象只是一個類,所以這不成問題。 這是MVVM中可能有點灰色的那些區域之一._ –