将实体框架与WPF DataBinding一起使用的最佳实践

entity-framework wpf

我正在构建我的第一个真正的WPF应用程序(即第一个打算供我以外的人使用),我仍然围绕着在WPF中做事的最佳方式。这是一个相当简单的数据访问应用程序,使用仍然相当新的实体框架,但我无法在线找到大量的指导,以便将这两种技术(WPF和EF)结合使用的最佳方式。所以我想我会抛弃我接近它的方式,看看是否有人有更好的建议。

  • 我正在使用SQL Server 2008的实体框架.EF让我觉得它比它需要的要复杂得多,而且还不成熟,但Linq-to-SQL显然已经死了,所以我不妨使用这项技术MS似乎专注于。

  • 这是一个简单的应用程序,所以我(还)认为不适合在它周围构建一个单独的数据层。当我想获取数据时,我使用相当简单的Linq-to-Entity查询,通常直接来自我的代码隐藏,例如:

    var families = from family in entities.Family.Include("Person")
               orderby family.PrimaryLastName, family.Tag
               select family;
    
  • Linq-to-Entity查询返回IOrderedQueryable结果,该结果不会自动反映基础数据的更改,例如,如果我通过代码向实体数据模型添加新记录,则此新记录的存在不会自动反映在引用Linq查询的各种控件。因此,我将这些查询的结果抛入ObservableCollection,以捕获底层数据更改:

    familyOC = new ObservableCollection<Family>(families.ToList());
    
  • 然后我将ObservableCollection映射到CollectionViewSource,这样我就可以进行过滤,排序等,而无需返回数据库。

    familyCVS.Source = familyOC;
    familyCVS.View.Filter = new Predicate<object>(ApplyFamilyFilter);
    familyCVS.View.SortDescriptions.Add(new System.ComponentModel.SortDescription("PrimaryLastName", System.ComponentModel.ListSortDirection.Ascending));
    familyCVS.View.SortDescriptions.Add(new System.ComponentModel.SortDescription("Tag", System.ComponentModel.ListSortDirection.Ascending));
    
  • 然后我将各种控件和what-not绑定到CollectionViewSource:

    <ListBox DockPanel.Dock="Bottom" Margin="5,5,5,5" 
        Name="familyList" 
        ItemsSource="{Binding Source={StaticResource familyCVS}, Path=., Mode=TwoWay}" 
        IsSynchronizedWithCurrentItem="True" 
        ItemTemplate="{StaticResource familyTemplate}" 
        SelectionChanged="familyList_SelectionChanged" />
    
  • 当我需要添加或删除记录/对象时,我从实体数据模型和ObservableCollection手动执行此操作:

    private void DeletePerson(Person person)
    {
        entities.DeleteObject(person);
        entities.SaveChanges();
        personOC.Remove(person);
    }
    
  • 我通常使用StackPanel和DockPanel控件来定位元素。有时我会使用Grid,但似乎很难维护:如果要在网格顶部添加新行,则必须触摸网格直接托管的每个控件,以告诉它使用新行。 Uggh。 (微软似乎从未真正获得DRY概念。)

  • 我几乎从不使用VS WPF设计器来添加,修改或定位控件。 VS附带的WPF设计器对于查看表单的外观有点模糊,但即使如此,也不是真的,特别是如果您使用的数据模板不能绑定到可用的数据模板设计时间。如果我需要编辑我的XAML,我会像男人一样手动操作。

  • 我的大部分真实代码都是使用C#而不是XAML。正如我在其他地方提到的那样,完全不同于我还不习惯“思考”它的事实,XAML让我觉得它是一种笨重,丑陋的语言,也恰好伴随着糟糕的设计师和智能感知支持,而且无法调试。 Uggh。因此,每当我能够清楚地看到如何在C#代码中执行某些操作时,我无法轻易地看到如何在XAML中执行操作,而是在C#中执行此操作,并且没有道歉。关于如何在WPF页面中使用代码隐藏(例如,用于事件处理)这是一个很好的做法,已经有很多文章,但至少到目前为止,这对我来说毫无意义。当我能使用像C#一样漂亮,干净的语言,拥有世界一流的编辑器,近乎完美的时候,为什么我应该用一种难看的,笨重的语言做一些语法,一个令人难以置信的语法,一个令人惊讶的糟糕的编辑器,几乎没有类型的安全性intellisense,无与伦比的安全性?

这就是我所处的位置。有什么建议?我错过了这方面的任何重要部分吗?我应该考虑采取哪些不同的做法?

一般承认的答案

您需要实现存储库模式以从EF中分离WPF问题

然后,您可以使用泛型来降低EF到CollectionViewSource处理的复杂性

设计良好的存储库应该降低代码级别并允许替换任何ORM(适当的测试需要)

对此的一些想法就在这里

http://blog.nicktown.info/2008/12/10/using-a-collectionviewsource-to-display-a-sorted-entitycollection.aspx


热门答案

另外,我认为你不需要在这里做一个ToList()。我相信ObservableCollection()接受一个家庭已经存在的IEnumerable。如果您执行ToList,然后将其传递给ObservableCollection,那么我认为您将遍历所有记录两次。

familyOC = new ObservableCollection<Family>(families.ToList());

相反,尝试这个,这应该更快一点:

familyOC = new ObservableCollection<Family>(families);



许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因
许可下: CC-BY-SA with attribution
不隶属于 Stack Overflow
这个KB合法吗? 是的,了解原因