有没有办法在 ado .net 中使用完全限定的 sql 列名?
Is there a way to use fully qualified sql column names in ado .net?
我正在努力将数据库(大约 30 table 秒)连接到我的 .net Web API。
现在我使用以下代码:
public static int GetIntNullCheck(IDataRecord reader, string columnName, int valueIfNull = -1)
{
if (reader == null)
throw new ArgumentNullException(nameof(reader));
int ordinal = reader.GetOrdinal(columnName);
return reader.IsDBNull(ordinal) ? valueIfNull : reader.GetInt32(ordinal);
}
因为我的一些查询连接了许多 table,所以我想使用完全限定的列名来访问结果。
在 ado.net 中有没有一种干净的方法来做到这一点?互联网上有多个关于此主题的已回答问题,但在我的情况下,每个解决方案都是黑客或不切实际。
想过但不想用的东西:
1.对冲突的列名称使用 SQL 列别名
这在理论上是可行的,但我的查询已经非常大了,对于每个查询 20 多个列这样做是不切实际的
2。更改数据库以在整个数据库中具有唯一的列名称
这可能是最现实的解决方案,但列名变得非常混乱。如果我没有其他选择,我必须这样做,但我真的很想避免它。
3。使用SQLDataReader.GetSchemaTable()
自己写这个功能
首先我不喜欢这个,因为它感觉像是一个 hack,并且可能对性能不利。此外,这不适用于 table 别名,但我必须在我的一些自连接查询中使用这些别名。尽管如此,我还是尝试实现它,但我只在 table 的 BaseTableName
字段上获得空值,尽管我使用 command.ExecuteReader(CommandBehavior.KeyInfo))
3。使用不同的数据库连接库
Ado.Net 被广泛使用,我主要使用许多人使用的库,因为它们更容易维护——如果我对它们有问题,几乎可以肯定互联网上有 100 个其他人有同样的问题并且有博客文章讨论解决方案。如果 ado.net.
中没有干净的方法,我会切换库
必须有一个好的方法来做到这一点。就像我提到的,有很多人有这个问题,ado.net 足够大,所以应该支持它。我只想能够使用 reader.GetOrdinal(tableName + "." + columnName);
。我总是将它与 java 中的 JDBC 一起使用,因此它必须可以从 SQL 侧
因此我的问题是:
我是否错过了一些可能的解决方案,或者您认为我描述的其中一个解决方案比我想象的要好?
tl;博士;美国别名。这就是他们在那里的目的。
Is there a way to use fully qualified sql column names in ado .net?
没有。结果集根据标识符的最后部分获取它的列名,即使您使用的是 multi-part 标识符 - 我很确定这不是 ADO.Net 的东西,因为它也发生在 SSMS 中(或我知道的任何其他数据库客户端)。
如果您 运行 在任何 SQL 服务器数据库上执行以下查询,您将自己看到它:
SELECT c.Name
, c.Name As [Column Name]
, T.Name
, T.Name As [Table Name]
FROM sys.Tables As T
JOIN sys.Columns As C
ON C.object_id = T.object_id
你得到的列名是这些:
Name Column Name Name Table Name
Things I thought about but do not want to use:
- Use SQL column aliases for conflicting column names
这实际上是该问题的最佳解决方案,因为它最容易实施和维护。
您不必为每个查询的所有列设置别名,只需为导致冲突的列设置别名。通常,不会那么多。
- Alter the database to have unique column names across the whole database
这似乎是一个可以接受的想法table,但它很快就会变得非常麻烦。
我曾经设计了一个数据库,所有列都以包含 table 的名称作为前缀。
当您有 table 时很容易,例如 Users
、Orders
或 Products
,它甚至有点有意义——当您在查询中看到 Order_Id
时,您确切地知道 table 它来自什么,你(至少在理论上)永远不需要任何别名 - 但是 - 我正在处理的数据库确实有一些 long-named tables - tables 在他们的名字中有 4、5 和 6 个词 - 所以我开始使用缩写 - 然后你得到像 PMTM_Something_Id
和哎呀这样的东西 - 有window 的可读性——如果你使用整个 table 名称,那就更糟了——我什至没有在谈论 many-to-many 关系的桥梁 table .
我不会再犯那个错误了。
- Use SQLDataReader.GetSchemaTable() to write this functionality myself
不要去那里。真的,不要。你只会让自己陷入比现在更糟的境地。
- Use a different database connection library
正如我在开头所写的那样 - 这不是 ADO.Net 的问题 - 这是 SQL 的问题 - 所以使用不同的数据库连接库不会解决这个问题。
我不确定 JDBC 是如何工作的,但是可以合理地假设 reader.GetOrdinal(tableName + "." + columnName);
完全按照 reader.GetOrdinal(columnName);
的方式进行操作。检查一下会很有趣,但是我最后一次在 Java 中写任何东西实际上是在上个千年 - 所以我什至不打算尝试。
我有点同意 Zohar 关于列别名的看法。
根据您的查询编写方式以及您对编码语言的熟悉程度,编写一个相对简单的实用程序(例如,c#)可能是可行的,它可以将您的原始 sql查询,自动添加需要的列别名,输出到另一个window ?
然后您的代码可以只使用具有所需列别名的查询。
我正在努力将数据库(大约 30 table 秒)连接到我的 .net Web API。 现在我使用以下代码:
public static int GetIntNullCheck(IDataRecord reader, string columnName, int valueIfNull = -1)
{
if (reader == null)
throw new ArgumentNullException(nameof(reader));
int ordinal = reader.GetOrdinal(columnName);
return reader.IsDBNull(ordinal) ? valueIfNull : reader.GetInt32(ordinal);
}
因为我的一些查询连接了许多 table,所以我想使用完全限定的列名来访问结果。 在 ado.net 中有没有一种干净的方法来做到这一点?互联网上有多个关于此主题的已回答问题,但在我的情况下,每个解决方案都是黑客或不切实际。
想过但不想用的东西:
1.对冲突的列名称使用 SQL 列别名
这在理论上是可行的,但我的查询已经非常大了,对于每个查询 20 多个列这样做是不切实际的
2。更改数据库以在整个数据库中具有唯一的列名称
这可能是最现实的解决方案,但列名变得非常混乱。如果我没有其他选择,我必须这样做,但我真的很想避免它。
3。使用SQLDataReader.GetSchemaTable()
自己写这个功能
首先我不喜欢这个,因为它感觉像是一个 hack,并且可能对性能不利。此外,这不适用于 table 别名,但我必须在我的一些自连接查询中使用这些别名。尽管如此,我还是尝试实现它,但我只在 table 的 BaseTableName
字段上获得空值,尽管我使用 command.ExecuteReader(CommandBehavior.KeyInfo))
3。使用不同的数据库连接库
Ado.Net 被广泛使用,我主要使用许多人使用的库,因为它们更容易维护——如果我对它们有问题,几乎可以肯定互联网上有 100 个其他人有同样的问题并且有博客文章讨论解决方案。如果 ado.net.
中没有干净的方法,我会切换库必须有一个好的方法来做到这一点。就像我提到的,有很多人有这个问题,ado.net 足够大,所以应该支持它。我只想能够使用 reader.GetOrdinal(tableName + "." + columnName);
。我总是将它与 java 中的 JDBC 一起使用,因此它必须可以从 SQL 侧
因此我的问题是:
我是否错过了一些可能的解决方案,或者您认为我描述的其中一个解决方案比我想象的要好?
tl;博士;美国别名。这就是他们在那里的目的。
Is there a way to use fully qualified sql column names in ado .net?
没有。结果集根据标识符的最后部分获取它的列名,即使您使用的是 multi-part 标识符 - 我很确定这不是 ADO.Net 的东西,因为它也发生在 SSMS 中(或我知道的任何其他数据库客户端)。
如果您 运行 在任何 SQL 服务器数据库上执行以下查询,您将自己看到它:
SELECT c.Name
, c.Name As [Column Name]
, T.Name
, T.Name As [Table Name]
FROM sys.Tables As T
JOIN sys.Columns As C
ON C.object_id = T.object_id
你得到的列名是这些:
Name Column Name Name Table Name
Things I thought about but do not want to use:
- Use SQL column aliases for conflicting column names
这实际上是该问题的最佳解决方案,因为它最容易实施和维护。
您不必为每个查询的所有列设置别名,只需为导致冲突的列设置别名。通常,不会那么多。
- Alter the database to have unique column names across the whole database
这似乎是一个可以接受的想法table,但它很快就会变得非常麻烦。
我曾经设计了一个数据库,所有列都以包含 table 的名称作为前缀。
当您有 table 时很容易,例如 Users
、Orders
或 Products
,它甚至有点有意义——当您在查询中看到 Order_Id
时,您确切地知道 table 它来自什么,你(至少在理论上)永远不需要任何别名 - 但是 - 我正在处理的数据库确实有一些 long-named tables - tables 在他们的名字中有 4、5 和 6 个词 - 所以我开始使用缩写 - 然后你得到像 PMTM_Something_Id
和哎呀这样的东西 - 有window 的可读性——如果你使用整个 table 名称,那就更糟了——我什至没有在谈论 many-to-many 关系的桥梁 table .
我不会再犯那个错误了。
- Use SQLDataReader.GetSchemaTable() to write this functionality myself
不要去那里。真的,不要。你只会让自己陷入比现在更糟的境地。
- Use a different database connection library
正如我在开头所写的那样 - 这不是 ADO.Net 的问题 - 这是 SQL 的问题 - 所以使用不同的数据库连接库不会解决这个问题。
我不确定 JDBC 是如何工作的,但是可以合理地假设 reader.GetOrdinal(tableName + "." + columnName);
完全按照 reader.GetOrdinal(columnName);
的方式进行操作。检查一下会很有趣,但是我最后一次在 Java 中写任何东西实际上是在上个千年 - 所以我什至不打算尝试。
我有点同意 Zohar 关于列别名的看法。
根据您的查询编写方式以及您对编码语言的熟悉程度,编写一个相对简单的实用程序(例如,c#)可能是可行的,它可以将您的原始 sql查询,自动添加需要的列别名,输出到另一个window ?
然后您的代码可以只使用具有所需列别名的查询。