2009-01-20 10 views
5

Ok, he logrado obtener el siguiente trabajoLINQ to SQL regreso de la función como IQueryable <T>

public IQueryable getTicketInformation(int ticketID) 
{ 
    var ticketDetails = from tickets in _context.tickets 
     join file in _context.file_objects on tickets.ticket_id equals file.source_id 
     where tickets.ticket_id == ticketID 
     select new { tickets.ticket_id, tickets.title, tickets.care_of_email, file.filename }; 

    return ticketDetails.AsQueryable(); 
} 

seguí adelante y creado mi propia clase (myObject) que contiene las primitivas ticket_id, título, care_of_email y nombre del archivo. ¿Cuáles son los artículos que estoy devolviendo en mi declaración de linq?

he modificado mi declaración para ser

public IQueryable<myObject> getTicketInformation(int ticketID) 
{ 
    var ticketDetails = from tickets in _context.tickets 
     join file in _context.file_objects on tickets.ticket_id equals file.source_id 
     where tickets.ticket_id == ticketID 
     select new { tickets.ticket_id, tickets.title, tickets.care_of_email, file.filename }; 

    return ticketDetails.AsQueryable()<myObject>; 
} 

pensando que esto lo haría un tipo seguro con los genéricos, pero me sale el error sistema "No se puede convertir grupo Método 'AsQueryable' de tipo no-delegado. Linq.IQueryable '. ¿Tuviste la intención de invocar el método?

¿Es lo que estoy tratando de hacer posible?

¿La clase myObject necesita implementar IEnumerable o IQueryable?

O es la mejor manera de construir el MiObjeto objeto desde el conjunto de resultados de LINQ y luego simplemente volver de la función del objeto MyObject

public myObject getTicketInformation(int ticketID) 
{ 

    ....linq statement.... 
    myObject o = null; 

    foreach (obj in linqstatemt) 
    { 
     o = new myObject(); 
     o.ticket_id = obj.ticket_id 
     ....... 
    } 
    return o; 
} 
+0

Pista, nombres de clase son PascalCased. – Dykam

Respuesta

14

decir:

select new MyObject { TicketId = tickets.ticket_id, 
    Title = tickets.title, ...}; 

(nota pellizqué los nombres ligeramente para ser más C# -idiomático)

Este es un "inicializador de objetos" que crea un nuevo MyObject (por registro) y asigna las propiedades de la s datos de origen. Lo que tenía era un inicializador de "tipo anónimo", que no es lo mismo. Tenga en cuenta que si usted tiene un constructor no predeterminado, también se puede usar algo como:

select new MyObject(tickets.ticket_id, tickets.title); 

que utiliza el constructor especificado, pasando de los valores suministrados desde la fuente de datos.

Esto será entonces IQueryable<MyObject>; no necesita llamar al .AsQueryable(). Tenga en cuenta que sería mejor que su función devuelva el formulario escrito (IQueryable<MyObject>) que el IQueryable sin tipo.

2

Como Marc dijo que no está construyendo instancias de myObject cuando se ejecuta su consulta. Pero, además, no es necesario que lo lances a un IQueryable<T>, un enunciado de selección LINQ devolverá un IQueryable<T> a menos que se explicite un IEnumerable<T>.

Además, tenga cuidado de que su DataContext no se haya eliminado antes de intentar acceder a los datos que se devuelven. Pero me di cuenta de que su contexto no está construido en el método, tenga cuidado de no mantener un DataContext durante demasiado tiempo, es un objeto de la unidad de trabajo y no debe permanecer abierto durante largos períodos de tiempo.

8

Esta línea es sintácticamente incorrecto:

return ticketDetails.AsQueryable()<myObject>; 

y debe leer

return ticketDetails.AsQueryable<myObject>(); 

Además, se está creando objetos anónimos con el select new {, pero desea crear myObject casos. Una aplicación correcta sería el siguiente:

public IQueryable<myObject> getTicketInformation(int ticketID) 
{ 

    return from tickets in _context.tickets 
     join file in _context.file_objects on tickets.ticket_id equals file.source_id 
     where tickets.ticket_id == ticketID 
     select new myObject() { 
      ticket_id = tickets.ticket_id, 
      title = tickets.title, 
      care_of_email = tickets.care_of_email, 
      filename = file.filename 
     }; 

} 

new SomeClass() { Property = value, ... La sintaxis crea una instancia SomeClass y establece las propiedades a los valores dados. Alternativamente, podría implementar un constructor en la clase myObject y llamarlo en la instrucción linq con select new myObject(...).

1

Gents, Todo tiene sentido siempre que solo devuelva una sola tabla, pero ¿y si hay que devolver dos o más?

RPDTDataContext smdt = new RPDTDataContext(); 
var projectedUsers = smdt.SM_Users.Join(
     smdt.SM_CTSGroups, u => u.CtsGroupID, c => c.id, 
     (u, c) => new { CTSGroup = c.Name, UserName = u.Name, u.EmpID, u.Email }); 
return projectedUsers;