ado.NET получает поля от читателя данных по полю И имени таблицы - PullRequest
0 голосов
/ 25 февраля 2011

Я использую только хранимые процедуры для выполнения каких-либо операций с БД.Я не хочу использовать ORB, прежде чем вы скажете, что :)

Для каждой таблицы у меня есть соответствующий класс DAO (VB или C #), например:

Namespace Dao

    Public Class Client

        Public Sub New(ByVal id As Integer, ByVal description As String)
            Me.id = id
            Me.description = description
        End Sub

        Property id As Integer
        Property description As String
     End Class

End Namespace

Конструкторстроит поля класса / свойства.В другом классе я обычно строю список (контейнер) своего класса DAO, вызывая хранимую процедуру SELECT, получая поля и создавая отдельные DAO:

Public Shared Function GetList() As List(Of Dao.Client)

    Dim model As New List(Of Dao.Client)

    Using dr As MySqlDataReader = DBUtils.CallReadingStoredProcedure("sp_get_clients")

        While dr.Read
            Dim client As New Dao.Client(dr.GetInt32(0), dr.GetString(1))
            model.Add(client)
        End While

        Return model
    End Using

End Function

Иногда мне нужно создать тот же Dao.класс из другого метода.Если полей для его построения много, было бы полезно вместо прямой передачи значений в конструктор DAO.class - который подвержен ошибкам - просто передать считыватель данных в другой конструктор, который извлекает поля и сам строит,

Это все равно, что передать ответственность за построение в сам Dao.class:

Namespace Dao

    Public Class Client

        Public Sub New(ByVal dr As DataReader)

            Me.id = dr.GetInt32("id")
            Me.marca_id = dr.GetInt32("marca_id")
            Me.categoria_id = dr.GetInt32("categoria_id")
            Me.codice = dr.GetString("codice")
            Me.descrizione = dr.GetString("descrizione")
            ... many other

        End Sub
...
    End Class

End Namespace

Таким образом, даже если я использую разные хранимые процедуры для получения клиентов, я использую один и тот же код для их построения,

Работает до тех пор, пока поля считывателя данных, то есть поля SELECT, всегда имеют одинаковые .Это возможно, но когда у меня есть JOIN, именованные поля не содержат имя таблицы, то есть с этим запросом в SP:

SELECT
        OA.id,              -- 0
        OA.articolo_id,         -- 1
        OA.quantita,            -- 2
        OA.quantita_evasa,      -- 3
        OA.prezzo,          -- 4
        A.id,               -- 5
        A.marca_id,         -- 6
        A.categoria_id,         -- 7
        A.codice,           -- 8
        A.descrizione,          -- 9
        A.prezzo_listino,       -- 10
        A.sconto,           -- 11
        A.prezzo_speciale,      -- 12
        A.ha_matricola,         -- 13
        A.unita_misura,         -- 14
        A.peso,             -- 15
        A.codice_barre,         -- 16
        other fields ...
    FROM nm_ordini_articoli OA
    JOIN articoli A ON (OA.articolo_id = A.id)
    other JOINs... 

Я не могу сделать dr.getInt32("OA.id"), потому что полеимя "id" и имя таблицы "OA".Я мог бы пойти с индексами, но это чистое безумие, так как я должен пытаться использовать одни и те же индексы для одних и тех же данных в разных хранимых процедурах!

Вопрос: я хочу конструктор Dao, который создает класс, дающий заголовок данных;как получить именованное поле из устройства чтения данных, включая псевдоним или имя таблицы?Я хочу сделать что-то вроде dr.getInt32("real table name", "field name") или dr.getInt32("table.field")

Другие советы?Спасибо.

Ответы [ 2 ]

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

Большая часть метаданных для результатов запроса доступна в DataTable, возвращаемом DataReader.GetSchemaTable. Детали таблицы зависят от поставщика, для SQL Server она задокументирована в SqlDataReader.GetSchemaTable, включая столбцы ColumnName, BaseColumnName и BaseTableName.

Помните, что возвращаемый столбец может быть вычислен в запросе и ему не дано имя, поэтому все они могут быть null.

0 голосов
/ 25 февраля 2011

Мой умный друг дал мне это элегантное и простое решение: используйте псевдонимы полей ... Это чертовски хорошо работает!

SELECT
        OA.id AS ordine_articolo_id, 
        ...
...