我正在开发一个应用程序,使工程师可以通过选择数据库,表,字段对我们的数据库进行简单的单表/视图查询。
我得到了如何使用动态LINQ库样本来在运行时动态选择Select,Where和Order by子句,但我对如何分配表选择感到困惑。
有没有一种方法可以在运行时动态选择“ from”表,您是否可以提供一些具体示例或将我指向有经验的人的方向?
真的非常感谢你。
编辑
因此,这两个答案似乎都说明了相同的总体思路。我将尝试将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
您可以使用GetTable()
获取数据的相应ITable
。然后结合使用DLINQ ,使其相对容易。
本示例使用AdventureWorks
数据库。我的项目具有在DatabaseTest.AdventureWorks
命名空间的DatabaseTest
程序集中定义的上下文。
'' 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)
请参阅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("...")