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

发布于 2024-10-17 21:52:19 字数 1697 浏览 0 评论 0原文

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

我了解了如何使用动态 LINQ 库示例来在运行时动态选择 Select、Where 和 Order by 子句,但我在如何分配表选择方面陷入了僵局。

有没有一种方法可以在运行时动态选择“来自”表,以及您如何提供一些具体的示例或为我指出有的人的方向?

非常感谢你。


编辑


所以这两个答案似乎都在说相同的一般想法。我将尝试将 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))

感谢您的帮助。乙肝病毒

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如日中天 2024-10-24 21:52:19

请参阅从 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("...")

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("...")
婴鹅 2024-10-24 21:52:19

您可以使用 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)

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文