2012-05-30 21 views
15

Estoy trabajando en un nuevo proyecto que necesita utilizar Linq To SQL. Se me ha pedido que cree una clase Linq to SQL genérica o reutilizable que se puede usar para ejecutar procedimientos almacenados.Crear reutilizable Linq a SQL para procedimientos almacenados

En ADO.Net yo sabía cómo hacer esto con sólo pasar de una serie de lo que quería ejecutar y pude pasar en diferentes cadenas para cada consulta que necesito para funcionar:

SqlCommand cmd = new SqlCommand("myStoredProc", conn); // etc, etc 

estoy luchando con cómo crear algo similar en Linq To SQL, si es posible. Creé un archivo .dbml y agregué mi procedimiento almacenado. Como resultado, puedo devolver los resultados utilizando el código de abajo:

public List<myResultsStoreProc> GetData(string connectName) 
{ 
    MyDataContext db = new MyDataContext (GetConnectionString(connectName)); 
    var query = db.myResultsStoreProc(); 

    return query.ToList(); 
} 

El código funciona pero ellos quieren que cree un método que devolverá procedimiento almacenado lo que digo para que se ejecute. He buscado en línea y hablé con colegas acerca de esto y no he tenido éxito en encontrar una manera de crear clases de proceso almacenadas reutilizables.

Entonces, ¿hay alguna manera de crear una clase Linq to SQL reutilizable para ejecutar procesos almacenados?

Editar:

Lo que estoy buscando es que si hay una manera de hacer algo como lo siguiente?

public List<string> GetData(string connectName, string procedureName) 
{ 
    MyDataContext db = new MyDataContext (GetConnectionString(connectName)); 
    var query = db.procedureName(); 

    return query.ToList(); 
} 

He revisado la MSDN docs en Linq To Sql y estos se muestra la tabla de la IEnumerable:

IEnumerable<Customer> results = db.ExecuteQuery<Customer>(
    @"select c1.custid as CustomerID, c2.custName as ContactName 
     from customer1 as c1, customer2 as c2 
     where c1.custid = c2.custid" 
); 

Estoy buscando algo muy genérico, donde puedo enviar en un valor de cadena de la almacenada proc que quiero ejecutar Si esto no es posible, ¿hay alguna documentación sobre por qué no se puede hacer de esta manera? Tengo que demostrar por qué no podemos pasar un valor de cadena del nombre del procedimiento para ejecutar en Linq To Sql

+0

¿Es necesario ejecutar procedimientos almacenados que puede que no haya modelados en el archivo .dbml? ¿Y desea devolver entidades que están mapeadas en su .dbml? – CodingGorilla

+0

lo más probable es que estén mapeados en el archivo .dbml, pero supongo que podría haber un caso en el que no fue – Taryn

+0

. Esta no es la forma en que se supone que debe usarse LINQ to SQL. Estás trabajando contra el sistema. Intente trabajar como debe ser usado. – usr

Respuesta

16

DataContext.ExecuteCommand no es exactamente lo que está buscando, ya que solo devuelve un valor int. Lo que quiere en su lugar es DataContext.ExecuteQuery, que es capaz de ejecutar un procedimiento almacenado y devolver un conjunto de datos.

Crearía una clase parcial para su DBML en la que almacenar esta función.

public List<T> GetDataNoParams(string procname) 
{ 
    var query = this.ExecuteQuery<T>("Exec " + procname); 

    return query.ToList(); 
} 

public List<T> GetDataParams(string procname, Object[] parameters) 
{ 
    var query = this.ExecuteQuery<T>("Exec " + procname, parameters); 

    return query.ToList(); 
} 

Para llamar a un procedimiento almacenado que haría:

GetDataNoParams("myprocedurename"); 

o

GetDataParams("myotherprocedure {0}, {1}, {2}", DateTime.Now, "sometextValue", 12345); 

o

GetDataParams("myotherprocedure var1={0}, var2={1}, var3={2}", DateTime.Now, "sometextValue", 12345); 

Si desea llamar a procedimientos sin valor de retorno que es bastante fácil también, ya que estoy seguro Puedes ver creando un nuevo método que no almacena/devuelve nada.

La inspiración provino del http://msdn.microsoft.com/en-us/library/bb361109(v=vs.90).aspx.

+0

¿El archivo DBML le dirá al método 'ExecuteQuery ' qué es 'T' para que los datos se puedan purgar en instancias de objetos? – bluevector

+0

No, dígale cómo es cuando lo llama. Mis ejemplos asumen que ya tiene objetos asignados a los tipos de devolución para cada procedimiento almacenado. Por lo tanto, si tiene un procedimiento almacenado que devuelve clientes y tiene un tipo de objeto de cliente, pase el cliente para T. – Peter

+0

Gotcha. Por lo tanto, no estamos tratando de obtener los procs almacenados 'IQueryable'-ify y nada debe ser omnisciente. – bluevector

2

La respuesta más simple a su pregunta es que se puede agarrar la propiedad Connection de su MyDataContext y crear y ejecutar sus propios SqlCommand s como lo harías en ADO.Net directo. No estoy seguro si eso servirá a sus propósitos, especialmente si desea recuperar entidades de su modelo LINQ a SQL.

Si desea devolver entidades del modelo, eche un vistazo al método DataContext.ExecuteCommand.

+0

Gracias por la dirección para esto, pero ¿puede proporcionar información adicional sobre cómo puedo pasar una cadena con el nombre del procedimiento que deseo ejecutar? . – Taryn

+0

@bluefeet Vea la respuesta de Peter, él tiene un par de ejemplos decentes. – CodingGorilla

0

Cuando dejamos caer una tabla o StoredProcedure en nuestro archivo .dbml crea su clase que se comunica con la capa de datos y nuestra lógica comercial.

En Linq a SQL tenemos que tener StoredProcedures o Tables presentes en el archivo .dbml, de lo contrario no hay forma de llamar a un método genérico en Linq a SQL para llamar a un procedimiento almacenado pasando su nombre a un método.

Pero en ADO.Net podemos hacerlo (como sabes)

SqlCommand cmd = new SqlCommand("myStoredProc", conn); 
Cuestiones relacionadas