WPF DataBindingでEntity Frameworkを使用するためのベストプラクティス

entity-framework wpf

質問

私は私の最初の本物のWPFアプリケーション(すなわち私以外の誰かによって使用されることを意図した最初のアプリケーション)を構築する過程にあります、そして私はまだWPFで物事をする最善の方法を頭に包みます。それはまだかなり新しいEntity Frameworkを使ったかなり簡単なデータアクセスアプリケーションですが、私はこれら2つの技術(WPFとEF)を一緒に使う最善の方法についてオンラインで多くのガイダンスを見つけることができませんでした。だから私は私がそれに近づいている方法を捨てて、誰かが何かもっと良い提案があるかどうかを確かめたいと思った。

  • 私はSQL Server 2008でEntity Frameworkを使用しています。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に対するwhat-notをバインドします。

    <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コントロールを使って要素を配置します。グリッドを使用することもありますが、管理が難しいようです。グリッドの最上部に新しい行を追加する場合は、グリッドで直接ホストされているすべてのコントロールにタッチして新しい行を使用するように指示する必要があります。うーん。 (MicrosoftはDRYの概念を理解したことがないようだ)

  • 私はVS WPFデザイナを使ってコントロールを追加、修正、配置することはほとんどありません。 VSに付属のWPFデザイナーは、フォームの外観を確認するのに非常に有用ですが、それでも、実際にはそうではありません。特に、で利用可能なデータにバインドしないデータテンプレートを使用している場合はなおさらです。デザインタイムXAMLを編集する必要がある場合は、男性のように編集して手動で編集します。

  • 私の本当のコードの大部分はXAMLではなくC#で書かれています。私がまだその中で「考える」ことに慣れていないという事実はとして、 他の場所で述べたように、XAMLは私を不格好で醜い言語として打っています。デバッグできません。うーん。その結果、CAMでコードビハインドを実行する方法をXAMLで簡単には理解できないことが明確にわかる場合は、謝罪することなくC#で実行します。 WPFページでコードビハインドを使用しないこと(たとえば、イベント処理のため)がどのようにして良い方法であるかについては多くのことが書かれていますが、少なくともこれまでは、まったく意味がありません。 C#のような、世界に通用するエディタを備えたきれいできれいな言語を使うことができるのに、どうして酷い文法、驚くほど悪いエディタ、そして事実上型保証のない醜い、不格好な言語で何かをやるべきなのです。インテリセンス、そして比類のないタイプの安全性?

だから私がいるところです。助言がありますか?私はこれの大きな部分を見逃していませんか?私は本当に違うやり方をするべきですか?

受け入れられた回答

WFの懸念をEFから切り離すためにリポジトリパターンを実装する必要があります。

その後、総称を使用して、CollectionViewSource処理に対するEFの複雑さを軽減できます。

うまく設計されたリポジトリはコードレベルを減らし、どんなORMでも代替できるようにするべきです(まともなテストに必要です)。

これに関するいくつかのアイデアはここにあります

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


人気のある回答

また、ここでToList()を実行する必要があるとは思わない。 ObservableCollection()は、どのファミリーがすでに存在しているかを示すIEnumerableを取ります。 ToListを実行してからそれをObservableCollectionに渡すと、すべてのレコードを2回ループすることになります。

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

代わりに、これを試してください。これは少し速いはずです。

familyOC = new ObservableCollection<Family>(families);


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ