Как я могу динамически выбирать мою Таблицу во время выполнения с Динамическим LINQ - PullRequest
0 голосов
/ 17 февраля 2011

Я разрабатываю приложение, позволяющее инженерам выполнять простые запросы к одной таблице / представлению к нашим базам данных, выбрав База данных, Таблица, Поля.

Я понимаю, как использовать пример динамической библиотеки LINQ для динамического выбора предложений «Выбрать, где и упорядочить по предложениям» во время выполнения, но я не могу понять, как распределять выбор таблиц.

Есть ли способ обеспечить динамический выбор таблицы "из" во время выполнения, и если как вы могли бы привести какой-то конкретный пример или указать мне в направлении кого-то, у кого есть?

Большое спасибо.


EDIT


Итак, оба ответа, похоже, говорят об одной и той же общей идее. Я собираюсь попытаться преобразовать 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

но выдает ошибку, утверждающую, что методы Extension могут быть определены только в модулях. Но когда я оборачиваю его в теги модуля, он все равно выдает ту же ошибку.

Итак, я получил его для компиляции, обернув его в теги модуля и удалив теги класса. Также я могу извлечь из нее последнюю строку и вставить ее непосредственно в базовый метод, который позволяет моему выполнить ее, но, похоже, она возвращается пустой. Когда я пытаюсь перечислить результаты, их нет. Не уверен, что это проблема с моими кодами или проблема с новыми кодами, я протестирую больше.


Вот мое преобразование второго примера. Теперь я ухожу, чтобы попытаться выяснить, смогу ли я заставить их работать. Я вернусь с вопросами или результатами после некоторого тестирования.

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

2 голосов
/ 17 февраля 2011

См. Получить данные таблицы из имени таблицы в 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 голос
/ 17 февраля 2011

Вы можете использовать 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)))

В ретроспективе, использование отражения могло бы быть более простым способом получить таблицу, поскольку у вас уже есть имя. Но тогда имена могут не иметь соответствия 1: 1, поэтому вам придется компенсировать это.

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