query for convert consulta c# linq-to-sql generics ienumerable iqueryable

c# - for - Linq a Sql regresa de la función como IQueryable<T>



linq for c# (4)

Ok, me las he arreglado para conseguir el siguiente trabajo

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 creé mi propia clase (myObject) que contiene las primitivas ticket_id, title, care_of_email y filename. ¿Cuáles son los artículos que estoy devolviendo en mi declaración de linq?

Modifiqué 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 podría hacer que escriba seguro con genéricos, pero me aparece el error "No se puede convertir el grupo de métodos ''AsQueryable'' al tipo no delegado ''System.Linq.IQueryable''. ¿Intentó invocar el método?"

¿Es lo que estoy tratando de hacer posible?

¿La clase myObject necesita implementar IEnumerable o IQueryable?

¿O es mejor construir el objeto MyObject desde el conjunto de resultados de linq y luego regresar de la función el 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; }


Como Marc dijo que no está construyendo instancias de myObject cuando se ejecuta su consulta. Pero, además, no es necesario convertirlo en una IQueryable<T> , una declaración de selección LINQ devolverá una IQueryable<T> menos que se explicite la IEnumerable<T> a 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.


Te refieres:

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

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

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

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

que usa el constructor especificado, pasando los valores suministrados de los datos fuente.

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


Esta línea es sintácticamente incorrecta:

return ticketDetails.AsQueryable()<myObject>;

y debería leer

return ticketDetails.AsQueryable<myObject>();

Además, está creando objetos anónimos con la select new { , pero desea crear instancias de myObject . Una implementación correcta se vería así:

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 }; }

La new SomeClass() { Property = value, ... crea una instancia SomeClass y establece las propiedades a los valores dados. De forma alternativa, podría implementar un constructor en la clase myObject y llamarlo en la sentencia linq con select new myObject(...) .


Gents, todo tiene sentido siempre que solo registren una sola mesa, 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;