O uso de procedimentos armazenados é uma maneira e tem sido amplamente utilizado por muitos anos.
Uma maneira mais moderna de interagir com os bancos de dados do SQL Server a partir de C # (ou qualquer linguagem .NET) é usar o Entity Framework. A vantagem do Entity Framework é que ele fornece um nível mais alto de abstração.
Para citar a Microsoft ( https://msdn.microsoft.com/en-us/data/jj590134 ):
O ADO.NET Entity Framework permite que os desenvolvedores criem aplicativos de acesso a dados programando em um modelo de aplicativo conceitual em vez de programar diretamente em um esquema de armazenamento relacional. O objetivo é diminuir a quantidade de código e manutenção necessária para aplicativos orientados a dados. Os aplicativos do Entity Framework fornecem os seguintes benefícios:
- Os aplicativos podem funcionar em termos de um modelo conceitual mais centrado em aplicativos, incluindo tipos com herança, membros complexos e relacionamentos.
- Os aplicativos são liberados de dependências codificadas em um mecanismo de dados ou esquema de armazenamento específico.
- Os mapeamentos entre o modelo conceitual e o esquema específico do armazenamento podem mudar sem alterar o código do aplicativo.
- Os desenvolvedores podem trabalhar com um modelo de objeto de aplicativo consistente que pode ser mapeado para vários esquemas de armazenamento, possivelmente implementados em diferentes sistemas de gerenciamento de banco de dados.
- Vários modelos conceituais podem ser mapeados para um único esquema de armazenamento.
- O suporte a consulta integrada à linguagem (LINQ) fornece validação de sintaxe em tempo de compilação para consultas em relação a um modelo conceitual.
O uso de um ORM vs procedimentos armazenados envolve compensações, principalmente em termos de segurança e onde a lógica reside.
A abordagem "clássica" ao desenvolvimento com o SQL Server é fazer com que a lógica do aplicativo resida nos procedimentos e programas armazenados, apenas com direitos de segurança para executar procedimentos armazenados, não para atualizar tabelas diretamente. O conceito aqui é que os procedimentos armazenados são a camada de lógica de negócios para os aplicativos. Embora a teoria seja sólida, ela tende a perder o interesse por várias razões, sendo substituída pela implementação da lógica de negócios em uma linguagem de programação como C # ou VB. Bons aplicativos ainda são implementados com uma abordagem em camadas, incluindo a separação de preocupações etc., mas são mais propensos a seguir um padrão como o MVC.
Uma desvantagem da implementação da lógica no ORM, e não no banco de dados, é a facilidade de depuração e teste das regras de integridade de dados pelos responsáveis pelo banco de dados (DA ou DBA). Pegue o exemplo clássico de transferência de dinheiro da sua conta corrente para a conta poupança, é importante que isso seja feito como uma unidade atômica de trabalho, ou seja, imprensado em uma transação. Se esse tipo de transferência apenas pode ser realizado por meio de um procedimento armazenado, é relativamente fácil para o DA e os auditores controlarem o controle do controle por controle de qualidade.
Se, por outro lado, isso é feito por meio de um ORM como o Entity Framework e na produção, é descoberto que, em raras ocasiões, o dinheiro é retirado da verificação, mas não colocado na depuração da economia, pode ser muito mais complexo, principalmente se vários programas estiverem potencialmente envolvidos. Provavelmente, esse seria um caso extremo, talvez envolvendo problemas peculiares de hardware que precisam ocorrer em uma sequência específica etc. Como testar isso?