2009-12-20 15 views
5

Tengo algún método linq a sql y cuando lo hace la consulta devuelve un tipo anónimo.¿Cómo devolver una colección de listas genéricas en C#?

Quiero devolver ese tipo anónimo a mi capa de servicio para hacer un poco de lógica y otras cosas.

No sé cómo devolverlo.

pensé que podía hacer esto

public List<T> thisIsAtest() 
{ 
    return query; 
} 

pero me sale este error

Error 1 The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?) 

así que no sé lo que me falta el montaje o si eso es aún el caso.

Gracias

EDIT

Ok mi primer problema fue resuelto, pero ahora tengo un nuevo problema que no estoy seguro de cómo solucionarlo ya que no sé mucho acerca de los tipos anónimos.

me sale este error

No se puede convertir implícitamente el tipo 'System.Collections.Generic.List' a 'System.Collections.Generic.List

Ésta es la consulta

DbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0) 
     .GroupBy(u => new { u.Table.Prefix }) 
     .Select(group => new { prefix = group.Key, 
           Marks = group.Sum(item => (item.Mark * item.Weight)/item.OutOFF) }) 
     .ToList(); 

Editar 2

public class ReturnValue 
{ 
    string prefix { get; set; } 
    decimal? Marks { get; set; } 
} 

public List<ReturnValue> MyTest(Guid userId) 
{ 
    try 
    { 
     var result = dbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0).GroupBy(u => new { u.Table.Prefix }) 
     .Select(group => new { prefix = group.Key, Marks = group.Sum(item => (item.Mark * item.Weight)/item.OutOFF) }).ToList(); 
     return result; 
    } 
    catch (SqlException) 
    { 
     throw; 
    } 

el selecto tiene esto en él

Anonymous Types: 

a is new{string Prefix} 
b is new{ 'a prefix, decimal? marks} 
+0

¿por qué no puede simplemente definir un nuevo tipo 'clase ReturnValue {int prefix; marcas decimales; } 'y luego devuelve un' nuevo ReturnValue (....) 'en lugar de un tipo anónimo ?? –

+0

Voy a necesitar un ejemplo. Recibí ayuda para hacer esta consulta, hago lo que quiero, pero si se puede cambiar o agregar algo para que no sea anónimo, estoy totalmente de acuerdo. – chobo2

+0

¡No estás usando el código que mencioné! En '.Select()', debe usar: '.Select (group => new RETURNVALUE {prefix = group.Key, ...' - esto es * NOT * lo que tiene! No agregó el ** TYPE ** se está creando en .Select(): ese es su problema –

Respuesta

8

no se puede - período. Usted no puede usar tipos anónimos fuera de su propio alcance, p. no puede devolverlos como valores devueltos por un método.

Si necesita devolverlos, debe definir una nueva clase concreta en lugar del tipo anónimo, y usar eso en lugar del tipo anónimo.

Sede de blog post en la determinación del alcance de los tipos anónimos, y ver a Rick Strahl la MSDN docs here cual claramente:

un tipo anónimo tiene ámbito de método. Para pase un tipo anónimo, o una colección que contiene tipos anónimos , fuera de un límite de método, usted primero debe convertir el tipo al objeto. Sin embargo, esto elimina la fuerte tipificación del tipo anónimo.Si debe almacenar los resultados de su consulta o pasarlos fuera del límite del método, considere usar una estructura o clase denominada ordinaria en lugar de un tipo anónimo .

Bien, claro, hay horribles hacks sucios para devolver tipos anónimos. Pero si Microsoft MSDN Y Jon Skeet desaconseja esa práctica, entonces - simplemente no lo haga. Por definición e intención, los tipos anónimos están ligados con el método que están definidos en

ACTUALIZACIÓN para chobo2:. No sé cuáles son sus tipos de datos son - sólo una suposición - pero asumiendo "prefijo" es un int y "marcas" es un decimal, se podría definir una clase nueva:

public class ReturnValue 
{ 
    int prefix { get; set; } 
    decimal Marks { get; set; } 
} 

y luego su código sería un método que devuelve un List<ReturnValue>:

public List<ReturnValue> thisIsAtest() 
{ 
    DbContext.Table.Where(u => u.Table.UserId == userId && u.OutOFF != 0) 
    .GroupBy(u => new { u.Table.Prefix }) 
    .Select(group => new ReturnValue 
          { prefix = group.Key, 
          Marks = group 
           .Sum(item => (item.Mark * item.Weight)/item.OutOFF) }) 
    .ToList(); 
} 

La clave aquí es: en su .Select método, en lugar de crear una nueva instancia de un tipo anónimo:

 .Select(group => new { prefix = group.Key, marks = .... } 

se crea una instancia de un tipo concreto:

 .Select(group => new ReturnValue { prefix = group.Key, marks = .... } 

De esta manera, usted tendrá una clase concreta ReturnValue - nombre eso que desee - y luego puede devolver fácilmente una lista de ese tipo, y usar ese tipo en otro lugar, también.

+0

En realidad, puedes: http://msmvps.com/blogs/jon_skeet/archive/2009/01/09/horrible-grotty-hack-returning-an-anonymous-type-instance.aspx No es que lo recomiende aunque. –

+0

Hmm puedo ver un ejemplo. Entiendo esto ahora. No quiero hacer lógica en mi capa de repositorio. De otro modo, tengo que hacer 2 de los mismos métodos porque lo uso para colocar pero necesito usar los datos de 2 maneras diferentes. No se puede convertir implícitamente el tipo 'System.Collections.Generic.List ' a 'System.Collections.Generic.List chobo2

+0

@MarkByers: pero el propio Jon dice: "no utilizan este código" .. ... así que realmente, para todos los propósitos: ** NO ** - ni siquiera lo intentes. –

6
public List<T> thisIsAtest<T>() 
{ 
    return query; 
} 
+0

Eso resolvió ese problema pero ahora lo consigo No se puede convertir implícitamente el tipo 'System.Collections.Generic.List ' a 'System .Collections.Generic.List chobo2

+1

La consulta que está devolviendo es una lista de tipos anónimos, solo puede devolver una lista de . Puede utilizar objetos y hack de conversión por Jon Skeet, pero no se recomienda encarecidamente. –

2

¿Desea devolver un tipo anónimo de un método normal? Estoy bastante seguro de que puedes hacerlo con Reflection, pero no habrá ningún tipo de seguridad y toda una serie de otros problemas. Sin mencionar que se ve raro desde la perspectiva de los códigos de llamada. Básicamente tendrías que devolver el objeto, creo.

Sería mejor utilizar una clase o estructura y rellenar los valores allí.

0

Los tipos anónimos son muy limitados, solo se pueden usar en el alcance del método en el que se declaran.

Puede devolverlos como objetos simples, pero luego pierde la información del tipo. He visto algunas soluciones pasando un tipo anónimo; pero usan la reflexión para recuperar las propiedades en un momento posterior.

Cuestiones relacionadas