With Dynamic LINQ, how can I dynamically choose my Table at runtime?

dynamic-linq linq linq-to-sql vb.net

Question

I'm developing an application to allow engineers to conduct simple single table/view queries 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

1
0
2/17/2011 8:03:53 PM

Accepted Answer

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)
1
2/17/2011 10:46:21 PM

Popular Answer

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("...")


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow