我在 VS 2010 (.Net 4.0) 中使用 EF 4.3.1 从数据库中加载许多参考表,以便将它们绑定到 WinForms 应用程序中的控件。
在表单加载时,我正在预取数据以便将其存储在本地,并且我正在创建一个 BindingSource 对象字典,我可以使用它来将本地数据绑定到控件。目的是尽量减少 EF 的自我验证对冷查询的影响,以便更快地加载表单并提高 UI 响应能力。
我编写了代码来为给定的 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() 返回一个 Object 而不是 DbSet(of T)。即使我通过反射知道类型,我也无法将对象转换为适当类型的 DbSet。
我无法访问 C# Dynamic 类型,而且我知道将泛型与反射混合起来很痛苦,但是有没有一种解决方案可以让我将反射的 DbSet 传递给我的函数?也许使用 Method.Invoke 的东西?