¿Cómo diferenciar los nombres de columna duplicates de diferentes tablas / subconsultas de origen por alias en una statement de selección de SQL cuando se usa SqlDataReader?

Supongamos que tengo entidades POCO que se leen desde una database y cada una de ellas tiene "ID" como su nombre de columna key principal.

Si selecciona de más de una tabla o subconsulta con alias a y b como select a.*, b.* from a, b , entonces las columnas seleccionadas includeán dos columnas de ID (a.ID y b.ID), pero la fuente los alias de tabla / subconsulta se pierden. Quiero saber si hay una manera de preservar o get dinámicamente dicho alias de nivel superior para el origen de las columnas de salida de una consulta de selección arbitraria.

Sé que puedo cambiar los nombres de columna de salida o acceder a ellos por ordinal, pero necesito acceder a las columnas por su nombre original + el alias de la tabla de origen / subconsulta, como "a.ID" y "b.ID".

SqlDataReader no parece conservar la información de la tabla base para las columnas de manera pnetworkingeterminada, y nunca conserva la información de alias.

¿Hay alguna forma de diferenciar estas columnas en SqlDataReader o hacer que preserve los alias de la tabla fuente / subconsulta para cada columna?

Aquí se formuló una pregunta similar: Diferenciar entre dos nombres de columnas SQL con el mismo nombre en una C # SqlConnection , pero la respuesta es dar a las columnas alias únicos, que no es lo que quiero. Quiero poder usar un alias para la tabla, conservando los nombres de columna originales.

Preguntado aquí: cómo get el nombre de la tabla de una columna de SqlDataReader y se responde aquí: https://stackoverflow.com/a/3111208/88409 , pero mencionan que no devolverá los alias de tabla, solo la tabla base original, que es inútil para subconsultas con alias.

ACTUALIZACIÓN: Parece que no se puede hacer. Una de las preguntas relacionadas con una pregunta decía que no había recibido respuesta, pero en realidad se respondía: Obteniendo esquema de tabla a partir de una consulta Parece que los alias son como "código fuente" para una consulta, y se eliminan durante el process de compilation / optimization que solo la información real de la table queda al final.

El otro tipo estaba equivocado, como sospechaba, así que voy a responder mi propia pregunta.

En SQL Server 2012 (y probablemente en versiones anteriores), encontré que si llamo 'set showplan_xml on;' en una consulta arbitraria como:

select * from (select * from Lessons a) a inner join (select * from LessonTypes b) b on a.LessonTypeID = b.ID;

El XML devuelto incluye lo siguiente como su primera / OutputList de nivel superior, que muestra claramente todas las columnas, y no solo sus tablas fuente, sino el alias de su subconsulta de origen.

 <OutputList> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="ID"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="Name"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="Description"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="Enabled"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="LessonTypeID"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[LessonTypes]" Alias="[b]" Column="ID"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[LessonTypes]" Alias="[b]" Column="Name"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[LessonTypes]" Alias="[b]" Column="Description"/> </OutputList> 

Entonces, en mi database API, como almaceno todas las cadenas de consultas orderadamente en un dictionary, puedo realizar un calentamiento de caching al inicio de la aplicación que las ejecuta con xml_showplan on, analizar las columnas de salida de nivel superior de XML y luego tener una asignación completa de alias de tabla y nombres de columna a su ordinal de salida.

En realidad, he usado un pequeño truco aquí. En realidad, no es el alias de la subconsulta, sino el alias de la tabla base. Si no incluye un alias en la tabla base, entonces el atributo Alias ​​no está presente en el XML. Sin embargo, es muy sencillo asegurarse de que cada vez que haga reference a una tabla real, le dé un alias, que debería provocar que se envíe al XML, y ahí lo tiene.

Para aclarar el punto, los alias se adhieren, incluso cuando se une a la tabla en una consulta como:

select * from Lessons a, Lessons b, Lessons c , que produce:

 <OutputList> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="ID"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="Name"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="Description"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="Enabled"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[a]" Column="LessonTypeID"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[b]" Column="ID"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[b]" Column="Name"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[b]" Column="Description"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[b]" Column="Enabled"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[b]" Column="LessonTypeID"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[c]" Column="ID"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[c]" Column="Name"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[c]" Column="Description"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[c]" Column="Enabled"/> <ColumnReference Database="[sensitive]" Schema="[dbo]" Table="[Lessons]" Alias="[c]" Column="LessonTypeID"/> </OutputList> 

Como puede ver, los alias están intactos y son recuperables.

Intereting Posts