< /p>
When the form loads, I get the data in advance so that it is stored locally, I am creating a dictionary of BindingSource objects, I can use it to bind local data to the control. The purpose is to minimize EF self-validation The impact on cold queries to load forms faster and improve UI responsiveness.
I wrote code to create and obtain BindingSource objects for a given DbSet collection, as shown below:
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< br /> ValidateBinding(Of T)(DbCollection)
Return _dictBindings(DbCollection.[GetType]().GetGenericArguments(0).Name)
End Function
It works, I can call
ValidateBinding(Db.ProvinceStates)
either
ComboBox1. DataSource = GetBinding(Db.Cities)
However, I want to call ValidateBinding on all DbSet collections in the model at startup, and I want to use reflection to iterate the available collections in the context because we are currently Load 66 tables and you can add more tables later.
I wrote the following code:
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
…But it can’t be used as propSet.GetValue() to return an Object instead of DbSet(T). I can’t cast the object to a DbSet of the appropriate type, even if I know the type through reflection.
Cannot access C#Dynamic types, I know it is a pain to mix generics with reflection, but is there a solution to pass the reflected DbSet to my function? Maybe something that uses Method.Invoke?
p>
First, I converted my function into an extension method. Although this is not necessary, it allows me to write:
db.ProvinceStates.ValidateBinding pre>and
ComboBox1.DataSource = db.Cities.GetBindingSecondly, I use GetMethod, MakeGenericMethod and Invoke to write the following:
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
methodValidateB inding.Invoke(Nothing, (oSet))
End If
NextThis will kill two birds with one stone, and load data for all 66 tables, and create a BindingSource object to bind the control To. (DbSetExtender is my own extension method module, and DbExtensions is part of the .Net framework.)
I am using EF 4.3 in VS 2010 (.Net 4.0) .1 Load a large number of reference tables from the database in order to bind them to the controls in the WinForms application.
When the form loads, I pre-fetch the data so that it is stored locally, I am creating A dictionary of BindingSource objects that I can use to bind local data to controls. The purpose is to minimize the impact of EF self-verification on cold queries, so as to load forms faster and improve UI responsiveness.
I wrote code to create and obtain BindingSource objects for a given DbSet collection, as follows:
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
This code is valid, I can Call
ValidateBinding(Db.ProvinceStates)
either
ComboBox1.DataSource = GetBinding( Db.Cities)
However, I want to call ValidateBinding on all DbSet collections in the model at startup, and I want to use reflection to iterate the available collections in the context, because we are currently loading 66 tables And you can add more tables later.
I wrote the following code:
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
...but it cannot Used as propSet.GetValue() to return an Object instead of DbSet(T). I also can’t cast the object to a DbSet of the appropriate type, even if I know the type through reflection.
I can’t access C# Dynamic type, I know that mixing generics and reflection is a pain, but is there a solution to pass the reflected DbSet to my function? Maybe something that uses Method.Invoke?
I think I have solved it, the solution is to use Method.Invoke.
First, I will my function Converted to an extension method. Although this is not required, it allows me to write:
db.ProvinceStates.ValidateBinding
and
ComboBox1.DataSource = db.Cities.GetBinding
Secondly, I use GetMethod, MakeGenericMethod and Invoke to write the following:
< pre>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
This will kill two birds with one stone, and load data for all 66 tables, and create a BindingSource object to bind the control to. (DbSetExtender is my own extension method module, and DbExtensions is part of the .Net framework.) p>