【问题标题】:Updating EF Model from a View in WPF从 WPF 中的视图更新 EF 模型
【发布时间】:2017-03-23 18:44:48
【问题描述】:

我在 WPF 应用程序中有一个主窗口和一些子窗口。使用 MVVM 和 EF。 以下是层的简化概述:

  • MainView:这里有一个 GridView 和一个保存按钮。
  • MainViewmodel:具有 ObservableCollection 属性和用于保存的 DelegateCommand。
  • ChildView:这里有一个 GridView 和一个保存按钮。
  • ChildViewmodel:具有 ObservableCollection 属性和用于保存的 DelegateCommand。
  • DataServices:使用提供 Entitytype1 和 Entitytype2 的 EF 模型

这是对代码的简化概述(对于子视图也是如此):

主视图中的 XAML

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

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

一切正常,数据显示在主视图的网格中。

现在的问题是:如何将数据取回数据库?

当用户更改网格中的某些内容时,它会在 ObservableCollection 中使用绑定进行更改,很好。

但是当用户单击视图上的保存按钮时,如何将更改返回到 DataServices 中的 EF 模型,然后返回到数据库?

我想我可以在 DataServices 中创建一个方法,将 ObservableCollection 放入并对其进行 foreach 并将其中的项目与 EF 模型中的所有项目进行比较以找到更改的项目。

但这似乎不对,有什么更好的方法?

【问题讨论】:

    标签: c# wpf entity-framework mvvm


    【解决方案1】:

    我几乎不建议不要将模型绑定到您的视图。您应该只将 ViewModels 绑定到您的视图。看看 MVVM 模式。

    当您通过 EF 从数据库加载数据时,您将获得一个项目列表。如果您遍历此列表,您可以为每个条目创建一个 ViewModel,并且每个 ViewModel 都可以存储从中创建的 EF 模型。保存数据时,您可以遍历 ViewModel 并获取更新的 EF 模型。当您创建了一个新的 ViewModel(没有 EF 模型)后,您可以创建一个新的 EF 模型。

    在我看来,这是一种非常简洁的方法,并且在我开发 WPF 应用程序近 10 年以来一直为我工作。

    【讨论】:

    • “将模型绑定到视图”是什么意思?我只将 ViewModel 绑定到我的视图。并且“为每个条目创建一个 ViewModel”是什么意思?这不是一个视图 - 一个视图模型吗?就像命名约定 MainView – MainViewmodel。还是我遗漏了什么,您能否提供一个 eksample。
    • 但是您的属性,例如MyEntityList 包含模型而不是 ViewModel。我正是这个意思。如果作为 View 的 DataContext 的 ViewModel 也使用 ViewModel 会更好。
    • 我读了很多关于 MVVM 的文章,看起来它并不是所有的固定规则。 _ 有人会说直接暴露实体不是纯粹的 MVVM,因为实体是模型,将模型暴露给 View 有点淘气。也有人说把数据拿到那个实体里面是模型层,实体对象只是一个类,所以没问题。这是 MVVM 中可能有些灰色的区域之一。_
    • 将模型绑定到视图时的问题是,您必须将特定于 UI 的代码放入模型中,例如 INotifyPropertyChanged。而且在实施时会遇到麻烦,例如撤消功能。
    【解决方案2】:

    我在需要时创建了 EF 模型,我猜想在应用程序的整个生命周期中都有一个 EF。是个坏主意吗?

    这取决于。在企业应用程序中,客户端应用程序一开始就不应该依赖实体框架。您通常会使用数据访问层 (DAL) 或服务或业务层与数据库进行通信,后者又在幕后调用 DAL。 EF 只存在于 DAL 中,客户端应用程序只是调用服务层的一些方法来读取和写入数据。它对EF一无所知,客户端也没有DbContext

    在小型应用程序中,在视图模型或整个应用程序的生命周期中使用单个 DbContext 可能是可以的。在这种情况下,您可以创建MyEntitiesModel 的单个实例,使用此上下文中的实体填充ObservableCollection&lt;T&gt;,然后在视图模型的Save() 方法中调用同一DbContext 实例的SaveChanges() 方法.

    我想我可以在 DataServices 中创建一个方法,将 ObservableCollection 放入并对其进行 foreach 并将其中的项目与 EF 模型中的所有项目进行比较以找到更改的项目。

    但这似乎不对,有什么更好的方法?

    您还可以将断开连接的实体附加到新的DbContext 实例并设置附加实体的状态。请参阅以下博客文章了解更多信息:https://blog.magnusmontin.net/2013/05/30/generic-dal-using-entity-framework/

    【讨论】:

    • 那么拥有一个带有视图 (MainView) 的客户端和一个带有 EF 模型的 DAL (DataServices),您将如何将更改后的数据从视图获取到 DAL?
    • 视图模型在命令的Execute方法中调用服务层或DAL。并且视图绑定到视图模型。
    • 正如我所建议的:我想我可以在 DataServices 中创建一个方法,将 ObservableCollection 放入并对其进行 foreach 并将其中的项目与 EF 模型中的所有项目进行比较以找到更改一。
    • 如前所述,要么就是这样,要么将实体附加到新的上下文中。顺便说一句,服务应该采用 IEnumerable 或 IList 而不是 ObservableCollection。 ObservableCollection 只属于客户端。
    • 如果您的问题已解决,请记住接受答案并为有用的答案投票:meta.stackexchange.com/questions/23138/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 2019-08-06
    • 1970-01-01
    • 2020-01-17
    • 1970-01-01
    相关资源
    最近更新 更多