將實體框架與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合法嗎? 是的,了解原因