2011-06-16 25 views
6

Tengo un procedimiento almacenado en una base de datos de SQL Server que devuelve una lista de resultados. Este procedimiento almacenado se expone en el archivo dbml LINQ-to-SQL. entonces trato de llamar a este procedimiento almacenado como tal:Procedimientos almacenados en LINQ-to-SQL

public List<MyObject> GetObjects() 
{ 
    List<MyObject> objects = new List<MyObject>(); 
    using (DatabaseDataContext context = new DatabaseDataContext()) 
    { 
    objects = context.GetObjectsFromDB(); // This is my problem line 
    } 
    return objects; 
} 

Mi problema es que no sé cómo convertir los resultados del procedimiento almacenado a una List<MyObject>. context.GetObjectsFromDB devuelve un System.Data.Linq.ISingleResult<sprocName>. ¿Cómo convierto el resultado del procedimiento almacenado en mi Lista de tipo fuerte predefinido?

¡Gracias!

+1

favor muestran código que se utiliza para llamar a procedimiento almacenado. –

+2

como nota al margen: la nueva puesta al día inicial de la lista es innecesaria (y derrochadora), el objeto de la lista inicial solo será GCed. – BrokenGlass

Respuesta

4

Prueba de esto,

public List<MyObject> GetObjects() 
{ 

using (DatabaseDataContext context = new DatabaseDataContext()) 
{ 
var objects = context.GetObjectsFromDB(); 
return new List<MyObject>(objects); 
} 
} 

Actualizado: Mediante el uso de conversión explícita se puede hacer como esto

public List<MyObject> GetObjects() 
{ 
using (DatabaseDataContext context = new DatabaseDataContext()) 
{ 
    List<MyObject> objects = (List<MyObject>)context.GetObjectsFromDB(); 
    return objects; 
} 
} 
+1

¿Por qué funciona esto? –

+0

@Justin: HERE VAR arroja implícitamente su objeto en el tipo de deseo y el compilador lo obtendrá en tiempo de ejecución ... También puede hacer esto haciendo fundición explícita y en su código no definió ninguna conversión ... – Syeda

+0

Ah, Veo lo que estás haciendo. Estaba confundido por la 'Lista objects = new List ();' en su versión original, que creo que no es necesaria. En realidad podría reemplazar todo en el bloque 'using' con' return (List ) context.GetObjectsFromDB(); 'y funcionaría bien. –

0

ISingleResult<T> hereda de IEnumerable<T>. Siempre que 'T' represente MyObject, debería poder iterar a través de la secuencia. Si 'T' es un tipo diferente, pondría un constructor en MyObject que toma el tipo DB y crea un MyObject a partir de él.

¿Ha intentado dejar caer un punto de interrupción después de la llamada SPROC para ver qué dice el depurador sobre el objeto que recibe?

0

La clase Enumerable también tiene una función miembro ToList que yo suelo usar para esto. http://msdn.microsoft.com/en-us/library/bb342261.aspx

Además, cuando uso Linq a Sql, siempre compruebo el resultado para null. Si espero una lista, verifique que el conteo sea mayor que cero antes de convertir a la lista.

public List<MyObject> GetObjects() 
{ 
    List<MyObject> objects = null; // no need to "new" here 
    using (DatabaseDataContext context = new DatabaseDataContext()) 
    { 
    var tmp = context.GetObjectsFromDB(); 
    if (tmp != null) 
    { 
     if (tmp.Count() > 0) 
     { 
     objects = (List<MyObject>)tmp.ToList(); 
     } 
    } 
    } 
    return objects; 
} 

Del mismo modo, si sólo se espera un resultado único, utilice

myObject = (MyObject)tmp.ToSingle(); 

Por último, es posible que desee considerar envolver esta función en un bloque try-catch y coger SqlException y controlar los errores de manera apropiada.

Solo menciono el manejo de error adicional debido a la experiencia en el desarrollo de aplicaciones que pueden fallar si no tiene el código adicional de manejo de errores.

0

Sé que es tarde, pero toooo ....

De LINQ Perpective, SP (no se utiliza la salida de resultado único) devolverá conjuntos de datos, por lo que crear una lista de lo que tiene que especificar el campo de regresar del SP :

objects = context.GetObjectsFromDB().Select(x => x.MyObject); 

es decir, el nombre del campo devuelto por el SP, como

objects = context.GetObjectsFromDB().Select(x => x.Names); 
0

que tenía el mismo problema!

Mi solución era hora de almacenarlo nueva versión para reemplazar la tabla temporal de las variables de tabla

Indiferente AUTO MAPA spAA_Result:

CREATE PROCEDURE spAA 
AS 
CREATE TABLE #TABLETMP (ID INT, NAME varchar(50)) 
    ... 
SELECT * FROM #TABLETMP 

AUTO mapa correcto CLASE spBB_Result:

CREATE PROCEDURE spBB 
AS 
DECLARE @TABLETMP AS TABLE (ID INT, NAME varchar(50)) 
    ... 
SELECT * FROM @TABLETMP 
0

Sí lo funcionaría es el siguiente:

List<string> listOfStrings = dbContext.spMyStoredProc().Select(x => x.Value).ToList<string>(); 

o

List<int> listOfInts = dbContext.spMyStoredProc().Select(x => x.Value).ToList<int>(); 
Cuestiones relacionadas