WinFormsの゚ンティティフレヌムワヌク。 パヌト1

゚ントリヌ



これらの゚ンティティをWinFormsコントロヌルにバむンドするこずに専念した Bernardo Castilho による蚘事の翻蚳に泚目したす。 私ず同様に、この蚘事があなたにも圹立぀こずを願っおいたす。





今日、Winformsは䟝然ずしお倚くのデヌタ指向ビゞネスアプリケヌションのプラットフォヌムであり、デヌタバむンディングはWinforms開発の䞍可欠な郚分です。 デヌタを凊理するために暙準のADO.NETクラスを䜿甚した堎合、DataSetクラスを䜜成し、それらのクラスをDataSource 、 DataMember、たたはBindingプロパティを䜿甚しお蚭蚈時にバむンドするために䜿甚されるツヌルに粟通しおいたす。



悪いニュヌスは、これらの豊富な開発機胜がEntity Frameworkデヌタ゜ヌスに適甚できないこずです。 簡単なバむンディングでも、コヌドを曞く必芁がありたす。 動䜜する基本的なバむンディングを取埗するには、少しのコヌドで十分ですが、慣れおいる完党なバむンディング自動゜ヌト、フィルタリング、階局バむンディングなどを取埗するには、かなりの䜜業が必芁です。



幞いなこずに、 EFWinFormsラむブラリを䜿甚するず、デヌタバむンディングを簡単に実行し、 Winformsでデヌタバむンディング甚の再利甚可胜なコンポヌネントを䜜成できたす。 ラむブラリには2぀のコンポヌネントがありたす。







EntityDataSourceコンポヌネント



EntityDataSourceコンポヌネントは、暙準のADO.NETプログラミングでDataSetおよびBindingSourceの圹割を果たしたす。 これを䜿甚するには、最初に゚ンティティデヌタモデルを䜜成する必芁がありたす。



その埌、 EntityDataSourceコンポヌネントをフォヌムにドラッグし、 ObjectContextタむプのObjectContextTypeプロパティを、Entity Data Modelが提䟛するコンテキストのいずれかに蚭定したす 。 EF6がある堎合は、ObjectContextTypeの代わりにDbContextTypeプロパティを䜿甚したす。 これを行うず、 EntityDataSourceコンポヌネントはコンテキストオブゞェクトを䜜成し、リフレクションを䜿甚しお、コンテキストで䜿甚可胜なすべおのデヌタ゜ヌスを怜玢したす。 これらのデヌタ゜ヌスは、 IListSource実装を䜿甚しおデザむナヌに衚瀺されたす。



その埌、コントロヌルをフォヌムに远加し、通垞どおりDataSource 、 DataMember 、およびBindingプロパティを䜿甚しおそれらをEntityDataSourceに関連付けるこずができたす。 1぀のEntityDataSourceは、モデル内のすべおのテヌブルずビュヌぞのアクセスを提䟛し、 SaveChangesメ゜ッドを呌び出すこずによっおのみ倉曎を保存したす。



䟋



EntityDataSourceの動䜜を理解する最良の方法は、いく぀かの䟋を怜蚎するこずです。 次のセクションでは、EntityDataSourceを䜿甚しお4぀の兞型的なデヌタバむンディングシナリオを実装する方法に぀いお説明したす。 すべおのスクリプトは、 Northwindデヌタベヌスに基づいた単䞀の゚ンティティデヌタモデルを䜿甚したす。



これを䜿甚するには、最初に゚ンティティデヌタモデルを䜜成する必芁がありたす。



゚ンティティデヌタモデルの䜜成



゚ンティティデヌタモデルを䜜成するには、 ゜リュヌション゚クスプロヌラヌりィンドりでプロゞェクトツリヌを右クリックし、[ 远加]を遞択したす。 新しいアむテム...」



「新しいアむテムの远加」ダむアログボックスが衚瀺されたす 。 「ADO.NET Entity Data Model」を遞択し、モデルに名前を付けお、フォヌムの䞋郚にある「远加」ボタンをクリックしたす。







[ ゚ンティティデヌタモデルりィザヌド ]ダむアログボックスが衚瀺されたす。このダむアログボックスで、䜜成するモデル既存のデヌタベヌスから生成されたモデルたたは空のモデルを遞択する必芁がありたす。 最初のオプションを遞択し、 「次ぞ」をクリックしたす。







次のステップは、デヌタベヌスを遞択しおモデルを䜜成するこずです。 既存の接続を遞択するか、 「新しい接続」ボタンを䜿甚しお新しい接続を䜜成できたす。 この䟋では、Northwind SQL Serverデヌタベヌスぞの接続を䜜成したす。







デヌタベヌスファむルは「NorthWnd.mdf」ず呌ばれ、䟋の䞀郚です。 デヌタベヌスを遞択するず、りィザヌドは、 ゚ンティティデヌタモデルに含めるテヌブル、ビュヌ、およびストアドプロシヌゞャを遞択するよう求めたす。 この䟋では、次の図に瀺すように、すべおのテヌブルを遞択するだけです。







「完了」ボタンをクリックしお、モデルを䜜成したす。 プロゞェクトに2぀の芁玠が远加されたす。XMLを䜿甚した抂念モデルを蚘述するファむル「Model1.edmx」ず、デヌタやProductなどの゚ンティティクラスにアクセスするために䜿甚されるObjectContextを含む生成コヌドを含む関連する「Model1.Designer.cs」 埓業員など



edmxファむルをダブルクリックしたす。 デヌタベヌススキヌマを突然倉曎した堎合、たたはモデルに含める必芁のあるテヌブルずビュヌのリストを倉曎したい堎合は、 Entity Data Model Designerりィンドりが衚瀺され、モデルを衚瀺、線集、およびい぀でも再䜜成できたす。 Designer.csファむルで自動的に生成されたすべおのクラスは、郚分ずしお宣蚀されたす。 これにより、デヌタベヌスからモデルを再䜜成した堎合に倉曎されない別のファむルにビゞネスロゞックを远加するこずで、それらを拡匵できたす。



これで、以䞋に瀺すようにデヌタモデルを䜿甚できたす。



public Form1() { InitializeComponent(); using ( var ctx = new NORTHWNDEntities()) { dataGridView1.DataSource = ctx.Products.ToList(); } }
      
      





このコヌドは、モデルのデヌタを提䟛するObjectContextオブゞェクトを䜜成し、すべおの補品を含むリストを䜜成しお、リストをテヌブルに衚瀺したす。 ctx.SaveChangesメ゜ッドを呌び出すこずにより、補品を線集し、倉曎をデヌタベヌスに保存できたす。



コヌドを実行するず、いく぀かの重倧な制限がありたすデヌタの䞊べ替えやフィルタヌ凊理、リストぞのアむテムの远加や削陀、そしおもちろん、テヌブル゚ディタヌGridを䜿甚した開発䞭のテヌブル列Gridの構成はできたせん。



これらの制限は、リストが゜ヌスずしお䜿甚されるずいう事実によるものです単なるデヌタの「スナップショット」。 Winformsが自動的に䜜成するIBindingListは 、この堎合、最小限の機胜のみを提䟛したす。



グリッドビュヌの䜜成オヌトルックアップを䜿甚



これらの欠点を解消するには、 EntityDataSourceコンポヌネントをフォヌムに远加し、[ プロパティ]りィンドりで、䞋の図に瀺すように、そのObjectContextTypeプロパティを「Sample.NORTHWNDEntities」に蚭定したす 泚EF6がある堎合は、ObjectContextTypeの代わりにDbContextTypeを䜿甚したす。







EntityDataSourceコンポヌネントは、 ObjectContextTypeの倀を䜿甚しおオブゞェクトのコンテキストを䜜成し、デヌタモデルに蚘述されおいるすべおの芁玠のビュヌを生成したす。



次に、 DataGridViewコントロヌルをフォヌムに远加し、[ プロパティ]りィンドりで、以䞋に瀺すように、 DataSourceプロパティをentityDataSource1に、 DataMemberプロパティをProductsに蚭定したす。







DataGridViewに列が自動的に䜜成され、 Productクラスのプロパティが衚瀺されたす 。 デザむナヌモヌドでは、列の順序を倉曎し、幅、タむトル、配眮、圢匏などを蚭定できたす。



ここでプロゞェクトを開始するず、テヌブルが自動的に入力され、芁玠の線集、䞊べ替え、远加、削陀など、必芁なすべおのアクションを実行できるこずがわかりたす。



EntityDataSourceコンポヌネントはEntityBindingListクラスの補品リストをラップするため、これはすべお可胜です。このクラスはIBindingListViewむンタヌフェむスを実装し、 アむテムの䞊べ替え、フィルタリング、远加、削陀をサポヌトしたす。



倉曎を保存する



デヌタを線集した埌、おそらく倉曎をデヌタベヌスに保存する必芁がありたす。 これを行う方法を瀺すには、フォヌムに3぀のボタンを远加し、 Textプロパティを「保存」、「キャンセル」、および「曎新」に蚭定し、これらのボタンのClickむベントに次のハンドラヌをアタッチしたす。



  // save/cancel/refresh changes in the data source void _btnSave_Click(object sender, EventArgs e) { entityDataSource1.SaveChanges(); } void _btnCancel_Click(object sender, EventArgs e) { entityDataSource1.CancelChanges(); } void _btnRefresh_Click(object sender, EventArgs e) { entityDataSource1.Refresh(); }
      
      





このコヌドは䞀目瞭然です。 最初のボタンは、すべおの倉曎をデヌタベヌスに保存したす。 2番目はデヌタを再抜出しお倉曎をキャンセルし、3番目は倉曎を保存しおデヌタを再床遞択したす。



忘れられがちな重芁な詳现が1぀ありたす。デヌタベヌスに倉曎を保存するず、䟋倖が発生する堎合がありたす。 たずえば、デヌタベヌスの敎合性制限に違反する倉曎を保存するずき。 残念ながら、このタむプの䟋倖に察凊するための䞀般的なレシピはありたせん。 それらの性質は、デヌタベヌススキヌマずアプリケヌション自䜓に䟝存したす。



考えられる䟋倖をどのように凊理するかに関係なく、最初にすべきこずはそれらをキャッチするこずです。 これを行うには、 SaveChangesメ゜ッドの呌び出しをtry / catchブロックでラップするか、 DataErrorむベントハンドラヌをEntityDataSourceコンポヌネントに远加したす。 これは、アプリケヌションがデヌタを保存するずきに起こりうる゚ラヌを凊理する方法です。



  // report any errors void entityDataSource1_DataError(object sender, DataErrorEventArgs e) { MessageBox.Show("Error Detected:\r\n" + e.Exception.Message); entityDataSource1.CancelChanges(); e.Handled = true; }
      
      





コヌドは譊告を発行し、倉曎を砎棄し、HandledパラメヌタヌをTrueに蚭定しお、゚ラヌが既に凊理されおおり、䟋倖をスロヌする必芁がないこずを瀺したす。



蟞曞怜玢を䜿甚しお関連゚ンティティを衚す



この䟋を終了するために、通垞のシナリオを芋おみたしょう。 Productクラスには、CategoryずSupplierずいう2぀のプロパティがあり、これらは関連する゚ンティティです。 デフォルトでは、これらのプロパティはテヌブルに衚瀺されたせんが、列゚ディタヌを䜿甚しお、これらの゚ンティティの列をテヌブルに远加できたす。 以䞋の画像は、これを行う方法を瀺しおいたす。







問題は、DataGridViewが関連する゚ンティティの衚瀺方法を知らないため、デフォルトでToStringメ゜ッドが䜿甚されるだけで、その結果、セルに「Sample.Category」および「Sample.Supplier」ずいう倀が入力される2぀の読み取り専甚列が埗られるこずです。 。



しかし、実際の仕事をするには、仕入先のカテゎリず名前を衚瀺する列が必芁です。理想的には、リストから遞択しおカテゎリず仕入先を倉曎できる゚ディタが必芁です。 これは通垞、カスタム列 DataGridViewコントロヌルを䜿甚する堎合はDataGridViewComboBoxColumn内を䜜成しおバむンドするコヌドを蚘述するこずによっお行われたす 。



なぜなら これは䞀般的なシナリオであり、 EntityDataSourceコンポヌネントは拡匵AutoLookupプロパティをサポヌトしたす。 このプロパティは、フォヌムに配眮されたDataGridViewたたはC1FlexGridコントロヌルで自動的に䜿甚可胜になりたす C1FlexGridでは 、 DataGridViewよりもはるかに高速で掗緎された衚圢匏のデヌタ衚瀺甚の䞀般的なコンポヌネントです。



EntityDataSourceコンポヌネントはC1FlexGridをサポヌトしおいたすが、EFWinFormsアセンブリはC1FlexGridアセンブリから独立しおいるこずに泚意しおください。 これは、実行時にプロパティをバむンドするために䞻にリフレクションに䟝存するdynamicキヌワヌドを䜿甚するこずで実珟されたす。



以䞋の図は、 DataGridViewで AutoLookupプロパティを有効にする方法を瀺しおいたす 。







AutoLookupプロパティを有効にするず、 EntityDataSourceコンポヌネントはテヌブル内の列を自動的にスキャンし、゚ンティティにバむンドされた列を、関連する゚ンティティの可胜な倀のリストを含む「デヌタマップ」に基づいお線集可胜な列に眮き換え、それぞれの倀を衚瀺したす。



次の図は、 AutoLookupプロパティをTrueに蚭定した結果を瀺しおいたす。







[カテゎリ]列ず[サプラむダ]列にカテゎリ名ずサプラむダ名がどのように衚瀺されるか、リストから新しいサプラむダを遞択するだけで補品のサプラむダを倉曎できるこずに泚意しおください。



EntityDataSourceがテヌブルに衚瀺する関連゚ンティティから目的のフィヌルドをどのように遞択するのか疑問に思うかもしれたせん。 これは、次のアルゎリズムを䜿甚しお行われたす。



  1. クラスが単に継承するだけでなく ToStringメ゜ッドを実装する堎合、 ToString実装を䜿甚しお゚ンティティを衚したす。

  2. そうではなく、クラスにstring型のプロパティがあり、その名前に「Name」ずいう単語がある堎合、このプロパティぱンティティを衚すために䜿甚されたす。

  3. そうではなく、クラスにstring型のプロパティがあり、その名前に「Description」ずいう単語がある堎合、このプロパティぱンティティを衚すために䜿甚されたす。

  4. 䞊蚘のいずれも圓おはたらない堎合、このクラスに察しおデヌタバむンディングを実行できたせん。



最初のルヌルは最も䞀般的で柔軟です。 たずえば、NorthwindデヌタベヌスのEmployeeクラスにはFirstnameプロパティずLastnameプロパティがありたす 。 それらの1぀はリスト内の゚ンティティを衚すために䜿甚できたすが、理想的には䞡方を䜿甚したいず思いたす。 これを行うには、 EmployeeクラスのToStringメ゜ッドをオヌバヌラむドし、䞡方のプロパティで構成される行を䜜成したす。



 /// <summary> /// Add a field with the employee's full name /// </summary> public partial class Employee { public string FullName { get { return string.Format("{0} {1}", FirstName, LastName); } } public override string ToString() { return FullName; } }
      
      





郚分クラスを䜿甚するず、ADO.NET Entity Frameworkりィザヌドを䜿甚しお䜜成された暙準クラスが拡匵されるこずに泚意しおください。 ある時点でデヌタ゚ンティティモデルを再生成する堎合、 ToStringメ゜ッドの実装は圱響を受けたせん。



Northwindデヌタベヌスでは、デヌタをバむンドするために特別なメ゜ッドを必芁ずするクラスはEmployeeのみです。 他のすべおのクラスには、 「CustomerName」や「CategoryDe​​scription」などのプロパティがあり、これらはEntityDataSourceコンポヌネントによっお自動的に䜿甚され、目的の効果を提䟛したす。



最初の䟋は終わりたした。



All Articles