ado.NET 通过字段和表名从数据读取器获取字段

Posted

技术标签:

【中文标题】ado.NET 通过字段和表名从数据读取器获取字段【英文标题】:ado.NET getting fields from a datareader by field AND table name 【发布时间】:2011-02-25 12:01:18 【问题描述】:

我只使用存储过程对数据库进行任何操作。在你说之前我不想使用 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.class。如果要构建它的字段很多,那么它会很有用,而不是将值直接传递给 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")之类的事情

其他建议? 谢谢。

【问题讨论】:

【参考方案1】:

查询结果的大部分元数据在DataReader.GetSchemaTable 返回的DataTable 中可用。该表的详细信息取决于提供程序,对于 SQL Server,它记录在 SqlDataReader.GetSchemaTable 中,包括列 ColumnNameBaseColumnNameBaseTableName

请记住,返回的列可能是在查询中计算出来的,但没有给出名称,所以它们都可以是 null

【讨论】:

【参考方案2】:

我的一个聪明的朋友给了我这个优雅而简单的解决方案:使用字段别名...... 效果很好!

SELECT
        OA.id AS ordine_articolo_id, 
        ...

【讨论】:

以上是关于ado.NET 通过字段和表名从数据读取器获取字段的主要内容,如果未能解决你的问题,请参考以下文章

怎样设置PostgreSQL中字段和表名对大小写敏感

MySQL根据字段名查找数据库名和表名

将表名从外部或变量传递给 INSERT INTO 表名?

Oracle 访问数据库字段和表名有大小写区分吗

Oracle 访问数据库字段和表名有大小写区分吗?

Oracle 访问数据库字段和表名有大小写区分吗?