【问题标题】:Best model for WPF+MVVM+EF 6.1WPF+MVVM+EF 6.1 的最佳模型
【发布时间】:2014-07-23 14:49:08
【问题描述】:

我正在尝试为我的 WPF+MVVM+EF 6.1 应用程序找出最佳模型,在观看了许多 EF 课程和博客之后,我对如何做到这一点有点困惑。在 WPF 中对应用程序建模时,需要 INotifyPropertyChanged、Observablecollection 并添加一些额外的计算属性(不保存在数据库中)。我正在考虑这个解决方案:

  1. 更改 EF T4 模板并实现 INotifyPropertyChanged,将集合更改为 Observablecollection 并在部分类中添加其他字段。这带来了与 EF 模型的绑定,但看起来简单且易于维护;
  2. 为域对象使用单独的类并在它们之间重写数据——例如使用自动映射器。这具有关注点分离,但所有更新和插入的实体都必须转换为适当的 EF 实体。
  3. 实现将 EF 类嵌套在新类中的新类,并封装所有属性并跟踪更改 - 另一方面,这会带来冗余代码。

不涉及编写冗余代码的最佳解决方案是什么?

【问题讨论】:

  • 视图模型怎么样?
  • ViewModel 怎么样?整个问题是如何在 ViewModel 中使用 EF 模型——当我从数据库中获取模型时,如何同步和绑定它?如何在模型和视图模型之间同步数据?直接用in还是用其他模型同步?

标签: wpf entity-framework mvvm


【解决方案1】:

如何按原样使用生成的 EF 实体并创建一个实现INotifyPropertyChanged 的 DTO 模型仅在必要时

并非在所有情况下都需要能够立即同步视图和模型之间的数据。

不要滥用INotifyPropertyChanged。当你意识到你有很多额外的代码实际上并不需要双向绑定,很多重复的工作并且可以'不能被其他客户端视图(可能是 asp.net)重用,因为它过于技术特定(例如依赖属性)。

MVVM 模式可以很好地用于简单的数据显示,而无需为绑定数据实现 INotifyPropertyChanged

public class Order
{
   public string OrderNo { get; set; }
   public DateTime Date { get; set; }
}
public class WindowViewModel
{
    public WindowViewModel()
    {
        var orders = Service<TheEntity>.Get();
        Array.ForEach(orders, order => Orders.Add(order));
    }

    private readonly ObservableCollection<Order> _orders = new ObservableCollection<Order>();
    public ObservableCollection<Order> Orders
    {
        get { return _orders; }
    }
}
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new WindowViewModel();
    }
}
<Window DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <ListView ItemsSource="{Binding Orders}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="OrderNo" DisplayMemberBinding="{Binding OrderNo}"/>
                <GridViewColumn Header="Date" DisplayMemberBinding="{Binding Date}"/> 
            </GridView>
        </ListView.View>
    </ListView>
</Window>

【讨论】:

  • 如果我理解正确,您是从我的列表中提出第二个选项?我不太明白这个例子展示了什么——你从某个服务加载一些实体到 Observable 集合,但是这个实体没有使用 INotifyPropertyChanged。更准确地说,我有来自 EF 的名为 A、B、C、D 和 E 的实体,我想在 ViewModel 中对它们进行操作。如果我理解正确的只读实体将直接绑定并且可编辑一次应该同步到某个 ViewModel 实体? AutoMapper 是正确的方法吗?如何在模型和视频模型之间同步数据?
  • 按原样使用 EF 实体,然后如果不可能使用第二个选项。该示例表明,对于一个简单的视图,您实际上不需要实现inotifypropertychanged,除非您以编程方式在视图模型中进行更改。 UI 的更改将在没有inotifypropertychanged 的情况下同步,但如果您在 vm 中进行更改并希望更新 ui,那么您需要该接口。但我仍然认为选项 2 违反了 DRY 原则.. 除非 UI 复杂且非常自定义
【解决方案2】:

最好的方法是不要干扰 EF 自动生成的代码,即使你将它包装在新类中,你仍然需要一些机制来跟踪和保存更改,这样做完全覆盖了实体框架的设计用途(在 DAL 中编码较少)。最好的方法是拥有属性(可观察的集合或我在 VM-View 模型中通知属性)。您可能需要在应用程序中添加更多代码,但这有助于您维护代码,并且它将与应用程序的其他模块(BL、DAL、..)完全分离。

【讨论】:

  • 如果我理解正确,您建议为所有 CRUD 实体设置单独的视图模型类,并在从数据库加载或保存数据时在它们之间同步数据? Automaper 是这个或其他技术的最佳选择吗?
  • @dnf 我曾经编写自己的映射器,因为它是小型应用程序。您必须检查在 PRISM 框架或其他一些 mvvm 框架中使用的一个,因为每个框架都有自己的优点/缺点。
猜你喜欢
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2017-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多