¿Cuál es la mejor manera de consultar datos de un servidor MS SQL en C #?
Sé que no es una buena práctica tener una consulta SQL en el código.
¿Es la mejor manera de crear un procedimiento almacenado y llamarlo desde C # con parámetros?
using (var conn = new SqlConnection(connStr))
using (var command = new SqlCommand("StoredProc", conn) { CommandType = CommandType.StoredProcedure }) {
conn.Open();
command.ExecuteNonQuery();
conn.Close();
}
c#
sql
sql-server
Bruno
fuente
fuente
// SQLCODE
hacerlo, pero debe recordar hacer eso.Respuestas:
El uso de procedimientos almacenados es unidireccional y se ha utilizado ampliamente durante muchos años.
Una forma más moderna de interactuar con las bases de datos de SQL Server desde C # (o cualquier lenguaje .NET) es usar Entity Framework. La ventaja de Entity Framework es que proporciona un mayor nivel de abstracción.
Para citar de Microsoft ( https://msdn.microsoft.com/en-us/data/jj590134 ):
ADO.NET Entity Framework permite a los desarrolladores crear aplicaciones de acceso a datos mediante la programación contra un modelo de aplicación conceptual en lugar de programar directamente contra un esquema de almacenamiento relacional. El objetivo es disminuir la cantidad de código y mantenimiento necesarios para las aplicaciones orientadas a datos. Las aplicaciones de Entity Framework brindan los siguientes beneficios:
El uso de un ORM vs Procedimientos almacenados implica compensaciones, particularmente en términos de seguridad y dónde reside la lógica.
El enfoque "clásico" para el desarrollo con SQL Server es hacer que la lógica de la aplicación resida en procedimientos almacenados y programas que solo tengan derechos de seguridad para ejecutar procedimientos almacenados, no actualizar tablas directamente. El concepto aquí es que los procedimientos almacenados son la capa de lógica de negocios para las aplicaciones. Si bien la teoría es sólida, ha tendido a caer en desgracia por varias razones, siendo reemplazada por la implementación de la lógica de negocios en un lenguaje de programación como C # o VB. Las buenas aplicaciones aún se implementan con un enfoque escalonado, incluida la separación de preocupaciones, etc., pero es más probable que sigan un patrón como MVC.
Una desventaja de implementar la lógica en el ORM en lugar de en la base de datos es la facilidad de depuración y prueba de las reglas de integridad de datos por parte de los responsables de la base de datos (DA o DBA). Tome el ejemplo clásico de transferir dinero de su cuenta corriente a su cuenta de ahorros, es importante que esto se haga como una unidad atómica de trabajo, en otras palabras, intercalado en una transacción. Si este tipo de transferencia solo se puede realizar a través de un procedimiento almacenado, es relativamente fácil para el DA y los auditores QA el procedimiento almacenado.
Si, por otro lado, esto se hace a través de un ORM como Entity Framework y en la producción se descubre que en raras ocasiones se extrae dinero de la verificación pero no se deposita en la depuración de ahorros puede ser mucho más complejo, particularmente si múltiples programas están potencialmente involucrados. Es muy probable que este sea un caso extremo, que tal vez implique problemas de hardware peculiares que deben ocurrir en una secuencia particular, etc. ¿Cómo se prueba esto?
fuente
En realidad, la afirmación básica es discutible: existen compensaciones de cualquier manera entre tener SQL en el código o tener código en la base de datos (que es a donde se dirige con los procedimientos almacenados).
El resultado de esto es que no existe un "mejor" único, esto no es algo que pueda generalizar porque, sea cual sea el camino que tome, se compromete (obtiene beneficios pero también introduce restricciones).
Si hay una correspondencia uno a uno entre su aplicación y su base de datos, entonces realmente no importa. Si, por otro lado, tiene una gran base de datos central compartida por un número significativo de aplicaciones, la aplicación de la coherencia dentro de la base de datos entre esas aplicaciones se vuelve mucho más importante.
Lo que es más importante es preocuparse por la arquitectura y las capas de su aplicación: dada una capa de acceso a datos adecuada, ya sea que use un ORM como Entity Framework o NHibernate o haga algo más directo, debe aislar la mayor parte de su aplicación de esta decisión, independientemente de si crea consultas o usar procedimientos almacenados.
Con toda libertad tendré a trabajar en proyectos relativamente pequeños con equipos pequeños (1-3 desarrolladores): el uso de procedimientos almacenados es, para mí, más problemático de lo que vale porque dada la naturaleza de nuestras aplicaciones (¿y mi conjunto de habilidades?) el código es generalmente mucho más fácil que actualizar el esquema (incluso permitiendo que tenga un código que hace que la actualización del esquema sea relativamente sencilla) y puedo hacer cumplir las reglas comerciales mediante el uso de un código de acceso a datos común. Este es claramente un ejemplo clásico de "Su millaje puede variar".
fuente
Mientras haya parametrizado sus entradas, cualquier enfoque es válido. Gran parte de las consultas de no tener argumentos en el código provienen de los viejos tiempos, cuando muchas de las bibliotecas lo forzaron a unir sus declaraciones en cadena y de ahí provienen los ataques de inyección SQL.
fuente
La mejor práctica es realmente exagerada aquí: hay muchas buenas maneras de hacerlo y la que elija realmente debería depender de cuál es su aplicación y qué debe hacer. Dicho esto, solo hay dos cosas que puedes hacer realmente mal:
Como señala @Bill, siempre debe parametrizar sus consultas. La creación de cadenas es un vector fácil para la inyección de SQL, así como todo tipo de errores difíciles de rastrear. Mucha gente más inteligente descubrió cómo tupelizar y escapar de sql, por lo que no es necesario que lo descubras tú mismo.
Cierra tus conexiones. La mejor manera es envolver todo con una declaración de uso, pero intentar / atrapar / finalmente también es genial si eso flota tu bote. Pero siempre asegúrese de usar una conexión como un automóvil barato: conduzca con fuerza y rapidez y deshágase de él rápidamente.
La otra práctica por la que argumentaría vehementemente es que debe asegurarse de concentrar su código de acceso a datos en la menor cantidad de lugares posible. No permitimos que las aplicaciones web front-end tengan una referencia directa a System.Data.SqlClient para ayudar a hacer cumplir esta advertencia.
fuente