.net 将Reflection.GetValue()对象强强制转换为泛型DbSet

.net 将Reflection.GetValue()对象强强制转换为泛型DbSet,.net,vb.net,entity-framework,generics,reflection,.net,Vb.net,Entity Framework,Generics,Reflection,我正在使用VS2010(.Net 4.0)中的EF 4.3.1从数据库加载大量引用表,以便将它们绑定到WinForms应用程序中的控件 在表单加载时,我将预取数据以便将其存储在本地,并创建一个BindingSource对象字典,用于将本地数据绑定到控件。其目的是最小化EF的自我验证对冷查询的影响,以便更快地加载表单并提高UI响应能力 我编写了代码,为给定的DbSet集合创建和获取BindingSource对象,如下所示: Private _dictBindings As New Dictiona

我正在使用VS2010(.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)

但是,我希望在启动时对模型中的所有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(t的)。我也不能将对象强制转换为适当类型的DbSet,即使我通过反射知道该类型


我没有访问C#动态类型的权限,我知道将泛型与反射混合在一起很痛苦,但是有没有一种解决方案可以让我将反射的DbSet传递给我的函数?也许是使用Method.Invoke解决的问题?

我想我已经解决了,解决方案是使用Method.Invoke

首先,我将函数转换为扩展方法。虽然这不是必需的,但它确实允许我写:

db.ProvinceStates.ValidateBinding

其次,我使用GetMethod、MakeGenericMethod和Invoke编写以下代码:

Dim methodLoad = GetType(DbExtensions).GetMethod("Load", BindingFlags.Static Or BindingFlags.Public)

For Each propSet As PropertyInfo In Db.GetType.GetProperties(BindingFlags.Instance Or BindingFlags.Public).Where(Function(P) P.PropertyType.IsGenericType)
   Dim oSet As Object = propSet.GetValue(Db, Nothing)
   methodLoad.Invoke(Nothing, {oSet})

   Dim methodValidateBinding = GetType(DbSetExtender).GetMethod("ValidateBinding", BindingFlags.Static Or BindingFlags.Public).MakeGenericMethod(propSet.PropertyType.GetGenericArguments(0))
   If methodValidateBinding IsNot Nothing Then
      methodValidateBinding.Invoke(Nothing, {oSet})
   End If
Next
这一举两得,加载所有66个表的数据,并创建绑定控件的BindingSource对象。(DBSetXtender是我自己的模块,我将扩展方法放在其中,而DbExtensions是.Net framework的一部分。)

ComboBox1.DataSource = db.Cities.GetBinding
Dim methodLoad = GetType(DbExtensions).GetMethod("Load", BindingFlags.Static Or BindingFlags.Public)

For Each propSet As PropertyInfo In Db.GetType.GetProperties(BindingFlags.Instance Or BindingFlags.Public).Where(Function(P) P.PropertyType.IsGenericType)
   Dim oSet As Object = propSet.GetValue(Db, Nothing)
   methodLoad.Invoke(Nothing, {oSet})

   Dim methodValidateBinding = GetType(DbSetExtender).GetMethod("ValidateBinding", BindingFlags.Static Or BindingFlags.Public).MakeGenericMethod(propSet.PropertyType.GetGenericArguments(0))
   If methodValidateBinding IsNot Nothing Then
      methodValidateBinding.Invoke(Nothing, {oSet})
   End If
Next