2010-11-23 127 views
12

Estoy tratando de decidir cuál es la mejor manera de llamar a un procedimiento almacenado.ASP.NET MVC: mejor manera de llamar al procedimiento almacenado

Soy nuevo en ASP.NET MVC y he estado leyendo mucho sobre Linq a SQL y Entity Framework, así como sobre el patrón de repositorio. Para ser sincero, estoy teniendo dificultades para entender las diferencias reales entre L2S y EF ... pero quiero asegurarme de que lo que estoy creando dentro de mi aplicación sea correcto.

Por ahora, necesito llamar correctamente a los procedimientos almacenados para: a) guardar información del usuario y obtener una respuesta y, b) tomar algo de información para un catálogo de productos.

Hasta ahora, he creado un archivo .dbml de Linq to SQL, seleccioné el procedimiento sotred del Server Explorer y lo arrastré a .dbml. Actualmente estoy llamando al procedimiento almacenado de este modo:

MyLinqModel _db = new MyLinqModel(); 
_db.MyStoredProcedure(args); 

sé que no tiene que estar más involucrados ... además estoy haciendo esto dentro de mi control, que entiendo que no es una buena práctica.

¿Alguien puede reconocer cuáles son mis problemas aquí?

Respuesta

19

LINQ y EF son probablemente excesivos si todo lo que estás tratando de hacer es llamar a un proceso almacenado.

Uso Enterprise Library, pero ADO.NET también funciona bien.

Ver this tutorial.

Brevemente (descaradamente copiado-y-pegar del artículo de referencia):

SqlConnection conn = null; 
    SqlDataReader rdr = null; 

    // typically obtained from user 
    // input, but we take a short cut 
    string custId = "FURIB"; 

    Console.WriteLine("\nCustomer Order History:\n"); 

     // create and open a connection object 
     conn = new SqlConnection("Server=(local);DataBase=Northwind; Integrated Security=SSPI"); 
     conn.Open(); 

     // 1. create a command object identifying 
     //  the stored procedure 
     SqlCommand cmd = new SqlCommand(
      "CustOrderHist", conn); 

     // 2. set the command object so it knows 
     // to execute a stored procedure 
     cmd.CommandType = CommandType.StoredProcedure; 

     // 3. add parameter to command, which 
     // will be passed to the stored procedure 
     cmd.Parameters.Add(
      new SqlParameter("@CustomerID", custId)); 

     // execute the command 
     rdr = cmd.ExecuteReader(); 

     // iterate through results, printing each to console 
     while (rdr.Read()) 
     { 
      Console.WriteLine(
       "Product: {0,-35} Total: {1,2}", 
       rdr["ProductName"], 
       rdr["Total"]); 
     } 
    } 

actualización

me perdí la parte en la que dijo que estaban haciendo esto en su controlador.

No, esa no es la forma correcta de hacerlo.

Su controlador solo debería estar involucrado en la orquestación de la construcción de la vista. Cree una biblioteca de clases separada, llamada "Capa de acceso a datos" o algo menos genérico, y cree una clase que maneje la invocación de sus procesos almacenados, la creación de objetos a partir de los resultados, etc. Hay muchas opiniones sobre cómo se debe manejar esto, pero quizás más común es:

View 
| 
Controller 
| 
Business Logic 
| 
Data Access Layer 
    |--- SQL (Stored procs) 
      -Tables 
      -Views 
      -etc. 
    |--- Alternate data sources 
      -Web services 
      -Text/XML files 
      -blah blah blah. 

MSDN has a decent tutorial on the topic.

+0

+1 para los modelos de acceso simple ADO.NET mientras que feo en la API sigue siendo el rey. No debería sorprendernos, ya que básicamente todas las demás tecnologías de acceso único a datos se reducen a ADO.NET. –

+3

Sí. Sabía que un tipo que tenía un desarrollador argumentaba que la biblioteca empresarial era más rápida que ado.net.ME ENCANTA la biblioteca empresarial, pero el DAAB engloba ado.net, por lo que es bastante tonto afirmar que es más rápido. ¡Sepa sus herramientas, muchachos! –

2

LINQ to SQL y ADO.NET EF adjuntar procs almacenados de lectura a la clase de contexto de datos/objetos que utiliza para hacer frente a sus diversas entidades. Para crear, actualizar y eliminar, puede crear un proceso que mapee las propiedades de una entidad generada por el modelo, y usando la ventana de asignación de entidades (olvide el nombre exacto en este momento), puede mapear un campo de entidades con los parámetros de proceso . Entonces, digamos que tiene una tabla de Clientes, EF genera una Entidad de Clientes, y puede mapear los parámetros de proc a las propiedades de la entidad Cliente al intentar actualizar/insertar/eliminar.

Ahora, puede asignar un procedimiento CUD a una función, pero no sé todas las repercusiones; Me gusta la forma en que acabo de mencionar lo mejor.

HTH.

-1

I patrón común es pasar una interfaz de repositorio en su controlador mediante inyección de dependencia. La elección de qué tecnología de persistencia/orm utiliza es realmente otro problema y no está relacionado con el hecho de que está utilizando MVC. Usar el patrón de repositorio y la codificación para abstracciones (interfaces) hace que su aplicación sea fácil de probar burlándose de sus repositorios.

Creo que también debería intentar utilizar la menor cantidad posible de procedimientos almacenados. Esto significa que puede probar más fácilmente su lógica de forma aislada (pruebas unitarias) sin necesidad de estar conectado a una base de datos. Recomiendo encarecidamente mirar NHibernate. La curva de aprendizaje es bastante empinada, pero usted tiene el control total de sus asignaciones y configuración. Obviamente hay ocasiones en las que necesitará procs almacenados por razones de rendimiento, pero usar un ORM predominantemente es muy beneficioso.

+8

Los procedimientos almacenados se deben usar cuando corresponda, no "lo menos posible". La primera vez que un DBA vino a mí para decirme que resolvió un problema de SQL que ni siquiera sabía que existía fue suficiente para convencerme de eso. Además, poder realizar comprobaciones en tiempo de compilación en su SQL, así como abstraer su capa de datos en componentes que pueden ser utilizados por múltiples aplicaciones en múltiples idiomas/plataformas, es un beneficio que no debe tomarse a la ligera. He visto proyectos de cráter porque el desarrollador decidió cambiar de idioma y tuvo que reescribir todas las consultas porque estaban incrustadas –

+0

@David, estuvo de acuerdo ... y esta es una de esas situaciones en las que está bien. – dcolumbus

+1

Sé que esto fue a partir de 2010, pero eché un vistazo a NHibernate una vez, recientemente, ¡ni siquiera pude hacer que compilara! También está desactualizado ya que su versión 1.1 (la última, que recuerdo) no era compatible con .NET 3.5, mucho menos 4.0. Las utilidades de terceros que requieren una aceleración considerable tampoco van a ser populares entre los gerentes que intentan ejecutar un proyecto (y se preocupan cuando se vayan a su próximo contrato). – vapcguy

-5

no me puedo imaginar que su objetivo es ser capaz de llamar a un procedimiento almacenado. Para mí, parece como si necesitaras olvidar los procedimientos almacenados y usar Linq en Sql. Digo L2S porque EF es mucho más que aprender, y no es necesario en este caso.

+4

¿Por qué crees que su objetivo no es llamar a un proceso almacenado, cuando dijo específicamente que lo era? –

3

Prueba esto:

Leer:

var authors = context.Database.SqlQuery<Author>("usp_GetAuthorByName @AuthorName", 
new SqlParameter("@AuthorName", "author")); 

Actualización:

var affectedRows = context.Database.ExecuteSqlCommand 
("usp_CreateAuthor @AuthorName = {0}, @Email= {1}", 
"author", "email"); 

Desde este enlace: http://www.dotnetthoughts.net/how-to-execute-a-stored-procedure-with-entity-framework-code-first/

Y me gustaría ir con el marco David mencionó animado, en vez de tener las rutinas en el controlador. Simplemente pase los resultados como IEnumerable<blah> desde una función en una clase de repositorio separada para una edición, pase una booleana para si la actualización tuvo éxito para una actualización.

Cuestiones relacionadas