如何使用Dynamic LINQ在运行时动态选择我的表

时间:2011-02-17 17:16:36

标签: vb.net linq linq-to-sql dynamic-linq

我正在开发一个应用程序,允许工程师通过选择数据库,表,字段对我们的数据库进行简单的单表/视图查询。

我了解如何使用动态LINQ库示例来提供在运行时动态选择Select,Where和Order by Clauses,但我对如何分配表选择抱有重要意义。

有没有办法在运行时动态选择“从”表格,如果你能提供一些具体的例子或指向某人的方向?

非常感谢你。


修改


所以这两个答案似乎都在说同样的一般观点。我将尝试将C#转换为VB并使其工作。

第一个答案转换为

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

但它给我一个错误,说明扩展方法只能在模块中定义。 但是当我将它包装在模块标签中时,它仍会产生相同的错误。

所以我通过将它包装在模块标签中并剥离类标签来编译它。此外,我可以拉出最后一行并将其直接推入我的基本方法,这允许我执行它,但它似乎回来了空。当我试图枚举结果时,没有。不确定这是我的代码问题还是新代码问题,我会测试更多。


这是我对第二个示例的转换,现在我要试着看看能不能让它们工作。经过一些测试后,我会回答问题或结果。

'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))

感谢您的帮助。 BBL

2 个答案:

答案 0 :(得分:2)

请参阅Get table-data from table-name in LINQ DataContext

使用直接SQL语句实际上可能更好。 LINQ会妨碍你。

VB转换:

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

用法:

Dim myDataContext as New MyCustomDataContext
myDataContext.GetTableByName("ORDERS").Where("...")

答案 1 :(得分:1)

您可以使用GetTable()获取相应的ITable数据。然后再使用DLINQ,使其相对容易。

此示例使用AdventureWorks数据库。我的项目在DatabaseTest命名空间中的DatabaseTest.AdventureWorks程序集中定义了上下文。

'' 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)))

回想起来,使用反射可能是获取表格的更简单方法,因为您已经拥有该名称。但是这些名字可能没有一对一的对应关系,所以你必须要补偿它。

Dim table As ITable = dc.GetType().GetProperty(tableName & "s").GetValue(dc, Nothing)