How can I dynamically select my Table at runtime with Dynamic LINQ
I'm developing an application to allow engineers to conduct simple single table/view queri开发者_Go百科es against our databases by selecting Database, Table, Fields.
I get how to use the Dynamic LINQ Library Sample to provide for dynamically selecting the Select, Where and Order by Clauses at runtime but I'm at an impass on how to allot for table choice.
Is there a way to provide for dynamically selecting the "from" table at run time, and if how could you provide some concrete example or point me in the direction of someone who has?
Thank You ever so much.
EDIT
So Both of the answers seem to be saying the same general Idea. I'm going to try to convert the C# into VB and get it to work.
The first answer converts to
NotInheritable Class DataContextExtensions
Private Sub New()
End Sub
<System.Runtime.CompilerServices.Extension> _
Public Shared Function GetTableByName(context As DataContext, tableName As String) As ITable
If context Is Nothing Then
Throw New ArgumentNullException("context")
End If
If tableName Is Nothing Then
Throw New ArgumentNullException("tableName")
End If
Return DirectCast(context.[GetType]().GetProperty(tableName).GetValue(context, Nothing), ITable)
End Function
End Class
but it's tossing me an Error stating that Extension methods can be defined only in modules. But when I wrap it in module tags it still gives the same error.
So I got it to compile by wrapping it in Module Tags and stripping the class tags. Also I can pull the last line out of it and shove that directly into my base method which allows my to execute it but, it seems to be coming back empty. When I try to enumerate the results there are none. Not sure if this is my codes problem or the new codes issue, I'll test more.
Here's my conversion of the second Example, Now I'm off to try to see if I can get them to work. I'll be back with questions or results after some testing.
'get the table from a type (which corresponds to a table in your context)
Dim dataContextNamespace = "My.DataContext.Namespace"
Dim type = Type.[GetType](dataContextNamespace + tableName)
Dim table = dc.GetTable(type
'add where clauses from a list of them
For Each whereClause As String In whereClauses
table = table.Where(whereClause)
Next
'generate the select clause from a list of columns
Dim query = table.[Select]([String].Format("new({0})"), [String].Join(",", selectColumns))
Thanks for the help. BBL
See Get table-data from table-name in LINQ DataContext.
This is probably actually better done by using direct SQL statements. LINQ will just get in your way.
VB Conversion:
NotInheritable Class DataContextExtensions
Private Sub New()
End Sub
<System.Runtime.CompilerServices.Extension> _
Public Shared Function GetTableByName(context As DataContext, tableName As String) As ITable
If context Is Nothing Then
Throw New ArgumentNullException("context")
End If
If tableName Is Nothing Then
Throw New ArgumentNullException("tableName")
End If
Return DirectCast(context.[GetType]().GetProperty(tableName).GetValue(context, Nothing), ITable)
End Function
End Class
Usage:
Dim myDataContext as New MyCustomDataContext
myDataContext.GetTableByName("ORDERS").Where("...")
You can use GetTable()
to get the corresponding ITable
of your data. Then coupled with using DLINQ, making it relatively easy.
This example uses the AdventureWorks
database. My project has the context defined in the DatabaseTest
assembly in the DatabaseTest.AdventureWorks
namespace.
'' need my database and DLINQ extensions up top
Imports DatabaseTest.AdventureWorks
Imports System.Linq.Dynamic
'' sample inputs
Dim dc = New AdventureWorksDataContext()
Dim tableName = "Contact"
Dim whereClauses() = {"FirstName = ""John"" OR LastName = ""Smith"""}
Dim selectColumns() = {"FirstName", "LastName"}
'' get the table from a type (which corresponds to a table in your database)
Dim typeName = "DatabaseTest.AdventureWorks." & tableName & ", DatabaseTest"
Dim entityType = Type.GetType(typeName)
Dim table = dc.GetTable(entityType)
Dim query As IQueryable = table
'' add where clauses from a list of them
For Each whereClause As String In whereClauses
query = query.Where(whereClause)
Next
'' generate the select clause from a list of columns
query = query.Select(String.Format("new({0})", String.Join(",", selectColumns)))
In retrospect, using reflection might have been the easier way to get the table since you have the name already. But then the names might not have a 1-to-1 correspondence so you'll have to compensate for it.
Dim table As ITable = dc.GetType().GetProperty(tableName & "s").GetValue(dc, Nothing)
精彩评论