Trabajo en una empresa que solo usa procedimientos almacenados para todo el acceso a datos, lo que hace que sea muy molesto mantener nuestras bases de datos locales sincronizadas como cada confirmación que tenemos para ejecutar nuevos procs. He usado algunos ORM básicos en el pasado y encuentro la experiencia mucho mejor y más limpia. Me gustaría sugerirle al gerente de desarrollo y al resto del equipo que analicemos el uso de un ORM de algún tipo para el desarrollo futuro (el resto del equipo solo está familiarizado con los procedimientos almacenados y nunca ha usado nada más). La arquitectura actual es .NET 3.5 escrita como .NET 1.1, con "clases de dios" que usan una implementación extraña de ActiveRecord y devuelven conjuntos de datos sin tipo que se agrupan en archivos de código subyacente; las clases funcionan de la siguiente manera:
class Foo {
public bool LoadFoo() {
bool blnResult = false;
if (this.FooID == 0) {
throw new Exception("FooID must be set before calling this method.");
}
DataSet ds = // ... call to Sproc
if (ds.Tables[0].Rows.Count > 0) {
foo.FooName = ds.Tables[0].Rows[0]["FooName"].ToString();
// other properties set
blnResult = true;
}
return blnResult;
}
}
// Consumer
Foo foo = new Foo();
foo.FooID = 1234;
foo.LoadFoo();
// do stuff with foo...
Prácticamente no hay aplicación de ningún patrón de diseño. No hay pruebas de ningún tipo (nadie más sabe cómo escribir pruebas unitarias, y las pruebas se realizan cargando manualmente el sitio web y hurgando). Mirando a través de nuestra base de datos tenemos: 199 tablas, 13 vistas, 926 procedimientos almacenados y 93 funciones. Aproximadamente 30 tablas se usan para trabajos por lotes o cosas externas, el resto se usa en nuestra aplicación principal.
¿Vale la pena seguir un enfoque diferente en este escenario? Estoy hablando de avanzar solo porque no se nos permite refactorizar el código existente ya que "funciona", por lo que no podemos cambiar las clases existentes para usar un ORM, pero no sé con qué frecuencia agregamos módulos nuevos. de agregar / arreglar módulos actuales, así que no estoy seguro de si un ORM es el enfoque correcto (demasiado invertido en procedimientos almacenados y conjuntos de datos). Si es la elección correcta, ¿cómo debo presentar el caso para usar uno? Fuera de mi cabeza, los únicos beneficios que puedo pensar es tener un código más limpio (aunque podría no serlo, ya que la arquitectura actual no es t construido con ORM en mente, por lo que básicamente estaríamos instalando ORM con jurado en futuros módulos, pero los antiguos seguirían usando los DataSets) y menos problemas para recordar qué scripts de procedimiento se han ejecutado y cuáles deben ejecutarse, etc. pero eso es todo, y no sé cuán convincente sería un argumento. La mantenibilidad es otra preocupación, pero por la que nadie excepto yo parece estar preocupado.
fuente
Respuestas:
Los procedimientos almacenados son malos, a menudo son lentos y aproximadamente tan eficientes como el código ordinario del lado del cliente.
[La aceleración generalmente se debe a la forma en que el cliente y la interfaz del procedimiento almacenado están diseñados y la forma en que las transacciones se escriben como ráfagas cortas y enfocadas de SQL].
Los procedimientos almacenados son uno de los peores lugares para poner código. Divide su aplicación en dos idiomas y plataformas de acuerdo con reglas que a menudo son aleatorias.
[Esta pregunta será rechazada para tener un puntaje de aproximadamente -30 porque muchas, muchas personas sienten que los procedimientos almacenados tienen poderes mágicos y deben usarse a pesar de los problemas que causan.]
Mover todo el código de procedimiento almacenado al cliente facilitará mucho las cosas para todos.
Todavía tendrá que actualizar el esquema y el modelo ORM de vez en cuando. Sin embargo, los cambios de esquema están aislados de los cambios de ORM, lo que permite cierta independencia entre las aplicaciones y el esquema de la base de datos.
Podrá probar, corregir, mantener, comprender y adaptar todos los procedimientos almacenados a medida que los reescribe. Su aplicación se ejecutará de la misma manera y se volverá mucho menos frágil porque ya no se está dividiendo en dos tecnologías diferentes.
Los ORM no son mágicos, y las buenas habilidades de diseño de bases de datos son absolutamente esenciales para que funcione.
Además, los programas con una gran cantidad de SQL del cliente pueden volverse lentos debido al mal pensamiento sobre los límites de las transacciones. Una de las razones por las que los procedimientos almacenados parecen ser rápidos es que los procedimientos almacenados obligan a un diseño muy, muy cuidadoso de las transacciones.
Los ORM no fuerzan mágicamente un diseño de transacción cuidadoso. El diseño de la transacción aún debe realizarse con el mismo cuidado que cuando se escribían los procedimientos almacenados.
fuente
Los procedimientos almacenados son buenos, son rápidos y muy eficientes y son el lugar ideal para colocar su código relacionado con los datos. Mover todo ese código al cliente hará que las cosas sean un poco más fáciles para usted como desarrollador del cliente (un poco, ya que aún tendrá que actualizar el esquema y el modelo ORM cuando commit los cambie) pero perderá todo ese código existente y hará su aplicación es más lenta y probablemente más frágil teniendo en cuenta la pérdida de todas esas habilidades sql.
Me pregunto si los DBA están sentados allí diciendo "oh, cada confirmación, tengo que retirar el cliente nuevamente, deberíamos mover todo el código a los formularios de base de datos".
En su caso, debería poder reemplazar el ORM personalizado existente (es decir, sus clases divertidas) con el de otra persona sin ninguna pérdida, excepto los cambios en la forma en que se escribe el código subyacente. También puede mantener los SP como la mayoría (¿todos?) ORM los llamará con gusto. Por lo tanto, recomendaría reemplazar esas clases "Foo" con un ORM y continuar desde allí. No recomendaría reemplazar sus SP.
PD. Parece que tiene mucho código común en las clases de código subyacente, lo que los convierte en un patrón de diseño en sí mismos. ¿Qué crees que es un patrón de diseño en primer lugar? (ok, puede que no sea el mejor, o incluso uno bueno, pero sigue siendo un DP)
Editar: y ahora con Dapper , cualquier razón para evitar sprocs sobre un ORM de peso pesado se ha ido.
fuente
ds.Tables[0].Rows[0]["FooName"].ToString()
basura. Gerente ama los procedimientos almacenados? Él se las queda. Pero sería físicamente imposible argumentar que mover todo ese repetitivo código repetitivo a algo generado por, por ejemplo, LINQ to SQL, fue algo malo.Parece que está tratando de llevar a su equipo de un extremo (procedimientos almacenados y conjuntos de datos) a otro (un ORM completo). Creo que hay otros cambios más incrementales que puede establecer para implementar para mejorar la calidad del código de su capa de acceso a datos, que su equipo podría estar más dispuesto a aceptar.
El código de implementación de registro activo a medio cocer que ha publicado no es particularmente elegante: recomendaría investigar el Patrón de repositorio que es fácil de entender e implementar, y es muy popular entre los desarrolladores de .NET. Este patrón a menudo se asocia con ORM, pero es igual de fácil crear repositorios usando ADO.NET simple.
En cuanto a DataSet's - ¡qué asco! Será mucho más fácil trabajar con sus bibliotecas de clases si devuelve objetos tipados estáticamente (o incluso dinámicos). Creo que esta ilustración explica mi opinión sobre DataSet mejor de lo que podría.
Además, puede deshacerse de los procesos almacenados sin saltar a un ORM; no hay nada de malo en usar SQL parametrizado. De hecho, definitivamente lo favorecería sobre el uso de procesos almacenados a menos que tenga procedimientos complejos que ahorren en múltiples viajes de ida y vuelta al servidor. Yo también odio cuando abro una base de datos heredada y veo una lista interminable de procedimientos CRUD.
No estoy desalentando el uso de ORM, generalmente los uso en la mayoría de los proyectos en los que trabajo. Sin embargo, puedo ver por qué puede haber mucha fricción al tratar de introducir uno en este proyecto y su equipo, lo cual, por decirlo amablemente, parece que dejaron de aprender cosas nuevas hace aproximadamente 8 años. Habiendo dicho eso, definitivamente echaré un vistazo a la nueva generación de "Micro ORM" como Dapper (utilizado para potenciar este sitio no menos) y Massive , los cuales son increíblemente fáciles de usar y lo mantienen más cerca del SQL que un ORM típico lo hace, y que su equipo podría estar más dispuesto a aceptar.
fuente
Estoy en una situación similar, en realidad nuestro hardware, poder y política se inclinan hacia el lado de la base de datos, por lo que todo pasa por un procedimiento almacenado. Desafortunadamente, son un dolor para un codificador, especialmente cuando se trata de metadatos y generación de código, ya que no hay metadatos tan ricos en procedimientos almacenados como tablas.
De todos modos, aún puede escribir código elegante y limpio utilizando los procedimientos almacenados. Actualmente estoy implementando el patrón Repository con todos los procedimientos almacenados. Sugeriría buscar en FluentAdo.net su brillante idea al mapear desde el lector de datos a sus objetos comerciales. Tomé un pedazo de esa idea y la reutilicé para mi solución local.
fuente
JFTR: soy un humilde desarrollador de PHP, pero esto parece un problema predominantemente político.
Dada la escala de la "podredumbre" que apuntala la aplicación, entonces, aparte de las mejores prácticas , habría una sobrecarga significativa para erradicarla. Esto suena como si estuviera bordeando el territorio de reescritura.
¿Puede garantizar que la alternativa que sugiere produciría beneficios para justificar el costo para el negocio? Sospecho que el ROI de esta empresa puede ser difícil de vender al negocio. A menos que la aplicación sea inestable, o pueda probar el mérito de la revisión en términos financieros, esto podría resultar difícil.
¿Es ORM la única alternativa a SPROCS? Hay un par de patrones de diseño entre un ORM completo y SQL vanilla. Quizás pueda comenzar el proceso llevando estos SPROCS gradualmente fuera de la base de datos a una DBAL. Existe el peligro, por supuesto, de que esto se convierta en un ORM casero con el tiempo, pero habría dado un paso más cerca del objetivo.
fuente
Cambiamos de SP a ORM hace unos años.
En un caso tuvimos que actualizar 80 tablas. El antiguo modelo de estimación habría estimado 80 horas para esto con entlib y SP. Lo hicimos en 10 :)
Nos ha dado una reducción del 80% en la cantidad de tiempo que usamos para desarrollar la capa de acceso a datos.
fuente
Me parece más que el problema subyacente es que sus implementaciones no funcionan correctamente y de forma automática.
Puede ser más fácil configurar un motor de construcción continua que sepa cómo manipular las bases de datos según sea necesario después de cada confirmación.
fuente