VS 2010(.Net 4.0)でEF 4.3.1を使用して、データベースから多数の参照テーブルをロードし、それらをWinFormsアプリのコントロールにバインドしています。
フォームの読み込み時に、ローカルに保存されるようにデータをプリフェッチし、ローカルデータをコントロールにバインドするために使用できるBindingSourceオブジェクトのディクショナリを作成しています。目的は、フォームの読み込みを高速化し、UIの応答性を向上させるために、コールドクエリに対するEFの自己検証の影響を最小限に抑えることです。
次のように、特定のDbSetコレクションのBindingSourceオブジェクトを作成してフェッチするコードを記述しました。
Private _dictBindings As New Dictionary(Of String, BindingSource)
Private Sub ValidateBinding(Of T As Class)(ByRef DbCollection As DbSet(Of T))
Dim strClassName As String = DbCollection.[GetType]().GetGenericArguments(0).Name
If Not _dictBindings.ContainsKey(strClassName) Then
_dictBindings.Add(strClassName, New BindingSource With {.DataSource = DbCollection.Local.ToBindingList})
End If
End Sub
Public Function GetBinding(Of T As Class)(ByRef DbCollection As DbSet(Of T)) As BindingSource
ValidateBinding(Of T)(DbCollection)
Return _dictBindings(DbCollection.[GetType]().GetGenericArguments(0).Name)
End Function
このコードは機能し、私は呼び出すことができます
ValidateBinding(Db.ProvinceStates)
また
ComboBox1.DataSource = GetBinding(Db.Cities)
ただし、起動時にモデル内のすべてのDbSetコレクションでValidateBindingを呼び出し、現在66個のテーブルを読み込んでおり、後でさらに追加できるため、リフレクションを使用してコンテキストで使用可能なコレクションを反復処理したいと思います。
私は次のコードを書きました:
For Each propSet As PropertyInfo In Db.GetType.GetProperties(BindingFlags.Instance Or BindingFlags.Public).Where(Function(P) P.PropertyType.IsGenericType)
ValidateBinding(propSet.GetValue(Db, Nothing))
Next
...ただし、propSet.GetValue()がDbSet(of T)ではなくObjectを返すため、機能しません。また、リフレクションでタイプがわかっていても、オブジェクトを適切なタイプのDbSetにキャストできません。
C#Dynamicタイプにアクセスできず、ジェネリックスとリフレクションを組み合わせるのは面倒ですが、リフレクトされたDbSetを関数に渡すことができるソリューションはありますか?おそらくMethod.Invokeを使用したものですか?