通过WPF DataBinding使用实体框架的最佳实践
我正在构建我的第一个真正的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));
然后,我将各种控件和什么不绑定到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控件来定位元素。 有时我会使用网格,但看起来很难维护:如果要在网格顶部添加新行,您必须触摸由网格直接托管的每个控件,以告诉它使用新行。 Uggh。 (微软从来没有真正看到DRY概念。)
我几乎从不使用VS WPF设计器来添加,修改或定位控件。 带有VS的WPF设计器对于查看你的表单将看起来有些模糊,但即便如此,并非如此,特别是如果你使用的数据模板不具有绑定到可用的数据设计时间。 如果我需要编辑我的XAML,我会像一个人一样手动完成它。
我的大部分真实代码都是用C#而不是XAML。 正如我在其他地方提到的,除了我还没有习惯于“思考”这个事实之外,XAML让我觉得这是一种笨重,丑陋的语言,也恰恰伴随着糟糕的设计和智能支持,而且不能被调试。 Uggh。 因此,只要我能清楚地看到如何在C#代码隐藏中做些什么,我不能轻易地看到如何在XAML中执行操作,我会在C#中执行此操作,而不会造成任何歉意。 关于如何在WPF页面中几乎从不使用代码隐藏(比如说,用于事件处理)是一种很好的做法,但至少至少对我来说,这对我来说毫无意义。 为什么我应该用一种丑陋,笨重的语言来做一些事情,语法错误,编辑令人吃惊,而且几乎没有类型安全性,因为我可以使用像C#这样具有世界级编辑器的完美干净的语言,几乎完美智能感知和无与伦比的类型安全?
这就是我所在的地方。 有什么建议么? 我是否错过了这个的大部分? 我真的应该考虑做什么不同的事情?
您需要实施一个存储库模式来分隔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);
我明白你来自哪里。 Josh Smith的这篇文章帮助我改变(或者开始改变)思维模式,这样你可以从WPF中受益,而不是将它看作是一个奇怪的,阻碍的,难以调试和不友好的框架!
链接地址: http://www.djcxy.com/p/84589.html上一篇: Best practices for using the Entity Framework with WPF DataBinding
下一篇: WPF image resources