visual utiliza sharp que programacion para lenguaje informacion evolucion antecedentes c# sql winforms orm data-access-layer

utiliza - ¿Dónde colocas declaraciones SQL en tus proyectos de c#?



lenguaje de programacion c (9)

Probablemente sea responsable de portar una aplicación vb6 a c #. Esta aplicación es una aplicación de Windows que interactúa con un acceso db. El acceso a los datos está encapsulado en objetos comerciales básicos. Una clase para una mesa básicamente. Los objetos comerciales vb6 existentes leen y escriben en el DB a través de DAO. He escrito DALs y ORMs varias veces antes, pero todos se dirigieron solo a SQL Server. Éste tendrá que dirigirse al servidor de acceso y sql. En proyectos anteriores, colocaba las cadenas de SQL en las partes privadas del objeto de negocio y tal vez movía el código sql redundante como conectar, crear comando, en una clase base común para reducir el código.

Esta vez, estoy pensando en escribir las cadenas de SQL en un archivo .settings o en algún otro archivo de texto de tipo clave / valor. Luego escribo una utilidad sql para editar este archivo y me permite ejecutar y probar las consultas parametrizadas. Estas consultas se referenciarán por nombre en el objeto comercial en lugar de incrustar el sql en el código.

Sé que un enfoque estándar es crear un DAL para cada base de datos dirigida y tener el estado de configuración que DAL usar. Realmente no quiero crear las dos clases DAL para cada base de datos. Parece que sería menos código si solo hiciera referencia a la consulta correcta por nombre clave y tuviera el tipo de conexión correcto.

Entonces, ¿están haciendo cosas como estas? ¿Cómo o si abordaste este problema? Que funciona mejor para usted?

¡Gracias!


Bueno, hay muchas opciones, así que realmente depende de cuáles son tus necesidades más apremiantes :-)

Un enfoque podría ser crear sentencias SQL como archivos de texto dentro de su solución VS, y marcarlas como "recurso incrustado" en la "acción de compilación". De esta forma, el SQL se incluye en el ensamblado resultante y se puede recuperar de él en tiempo de ejecución utilizando ResourceManifestStream del .NET Framework:

private string LoadSQLStatement(string statementName) { string sqlStatement = string.Empty; string namespacePart = "ConsoleApplication1"; string resourceName = namespacePart + "." + statementName; using(Stream stm = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) { if (stm != null) { sqlStatement = new StreamReader(stm).ReadToEnd(); } } return sqlStatement; }

Debe reemplazar "ConsoleApplication1" con su espacio de nombres real, en el que residen los archivos de declaración sql. Debe hacer referencia a ellos por medio del nombre completo. Luego puede cargar su instrucción SQL con esta línea:

string mySQLStatement = LoadSQLStatement("MySQLStatement.sql");

Sin embargo, esto hace que las consultas sean más bien "estáticas", por ejemplo, no puede configurarlas y cambiarlas en el tiempo de ejecución; se procesan directamente en los bits binarios compilados. Pero, por otro lado, en VS, tiene una buena separación limpia entre su código de programa C # y las sentencias SQL.

Si necesita poder modificarlos en tiempo de ejecución, los pondría en una sola tabla SQL que contiene, por ejemplo, una palabra clave y la consulta SQL real como campos. A continuación, puede recuperarlos según sea necesario y ejecutarlos. Dado que están en la tabla de la base de datos, también puede cambiarlos, corregirlos o modificarlos a voluntad, incluso en tiempo de ejecución, sin tener que volver a implementar toda la aplicación.

Bagazo


Cuando realmente lo necesito, coloco las consultas en archivos individuales * .sql, luego los incluyo en Resources.resx. Hay una sección ''Archivos'' en ella, que le permite incluir archivos de recursos incrustados.

Después de eso, puedo usar la propiedad Resources.MyQuery generada, que garantiza que el recurso existe y me evita escribir un método de carga de recursos personalizado.


Si tuviera que crear una aplicación para SQL y Access, usaría alguna interfaz IDAL, DALCommon con implementación de funcionalidad común y DALSql y DALAccess separados, heredados de DALCommon, con algunas cosas específicas, como excepciones, manejo de transacciones, seguridad, etc. .
Solía ​​mantener nombres de procedimientos almacenados o consultas en archivos de recursos.


Te diré dónde no voy a ponerlo nunca, algo que vi hecho en algún código que heredé. Fue en Java, pero se aplica a cualquier idioma

  • Una clase base que declaró las variables miembro estáticas protegidas para las sentencias SQL, inited to null, con un método get que devuelve declaraciones SQL individuales

  • Una subclase para cada servidor de base de datos compatible, con un método init que asigna a las variables miembro de la clase base

  • Varias clases DA que usan el método de clase base para recuperar sentencias SQL

  • La clase de puesta en marcha de la aplicación con la responsabilidad de crear el objeto de subclase correcto y llamar a su método init

Tampoco entraré a explicar por qué no haré esto nunca :-)


Un método que usamos es tener una clase que se conectaría a la base de datos y los métodos para llamar a los procedimientos y en el parámetro del método se proporcionaría el nombre del procedimiento. entonces todo el código SQL está en el procedimiento. usaríamos sobrecargas para los diferentes tipos de retorno

class ConnectToSQL() { //connectSql code (read from setting file i assume) XMLDataDocument runProcedure(string procedureName); int runProcedure(string procedureName); //etc.... }


LINQ to DataSet suena como el camino a seguir para usted.

Si no has usado el .NET 3.5 antes / LINQ, te espera una oportunidad. LINQ le ahorrará escribir su sql en bruto en cadenas literales y le proporcionará una forma más lógica de crear consultas.

De todos modos, consulte este enlace para usar las bases de datos de LINQ on Access - http://msdn.microsoft.com/en-us/library/bb386977.aspx


A veces, al igual que con las aplicaciones de generación de informes personalizados, realmente debe aceptar el desajuste de la impedancia y dar especial importancia al SQL. En estos casos, recomiendo lo siguiente: para cada módulo que contenga cadenas SQL, cree una única clase "SQL" estática para contenerlas todas. Algunas de las cadenas de SQL probablemente requerirán parámetros, por lo tanto, sea consistente y coloque cada cadena detrás de su propio método estático.

Solo hago esto para la aplicación ocasional de informes personalizados, pero siempre funciona muy bien y me resulta refrescante y liberador. Y es muy agradable volver meses después para hacer una mejora y encontrar todo el SQL esperándote en un único archivo SQL.cs. Con solo leer ese archivo, todo vuelve y, a menudo, este es el único archivo que debe modificarse.

No veo una necesidad en estos casos para ocultar el SQL en recursos o en otro lugar. Cuando SQL es importante, entonces es importante. Curiosamente, cada vez más desarrolladores están ahora mezclando libremente SQL con C #, incluido este sitio, porque esencialmente, eso es LINQ.

Finalmente, como siempre, asegúrese de no ser susceptible a ataques de inyección SQL. Especialmente si la entrada del usuario está involucrada, asegúrese de que está utilizando algún tipo de parametrización y que no está utilizando la concatenación de cadenas.


Es posible que las soluciones de incorporación que se muestran arriba no funcionen si SQL Query tiene una causa "where" similar, pero para la misma consulta, la siguiente ejecución necesita PropertyID = ''113'' como PropertyID read-in.


¡Me alegra que me lo hayas pedido Coloque su sql en una plantilla QueryFirst .sql.

Se compila automáticamente en su aplicación como un recurso incrustado, pero no le importa. Simplemente escríbelo, en una ventana de sql real, conectado a tu base de datos, con validación de sintaxis e intellisense para tablas y columnas, luego úsala, a través de los métodos Execute() generados, con intellisense para tus entradas y resultados.

descargo de responsabilidad: escribí QueryFirst.