Linq To Sql вернуть из функции как IQueryable <T> - PullRequest
5 голосов
/ 20 января 2009

Хорошо, мне удалось получить следующий рабочий

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

Я пошел дальше и создал свой собственный класс (myObject), содержащий примитивы. ticket_id, title, care_of_email и имя файла. Какие предметы я возвращаю в своем заявлении linq.

Я изменил свое утверждение, чтобы оно было

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

думая, что это сделает безопасность типов с помощью дженериков, но я получаю ошибку «Не удалось преобразовать группу методов« AsQueryable »в тип без делегатов« System.Linq.IQueryable ». Вы намеревались вызвать метод?»

Возможно ли то, что я пытаюсь сделать?

Должен ли класс myObject реализовывать IEnumerable или IQueryable?

Или лучше построить объект MyObject из набора результатов linq, а затем просто вернуть из функции объект 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;
}

Ответы [ 4 ]

14 голосов
/ 20 января 2009

Вы имеете в виду:

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

(заметьте, я немного подправил имена, чтобы они были более C # -диоматическими)

Это «инициализатор объекта», который создает новый MyObject (для каждой записи) и назначает свойства из исходных данных. То, что у вас было, было инициализатором «анонимного типа», что не то же самое. Обратите внимание, что если у вас есть конструктор не по умолчанию, вы также можете использовать что-то вроде:

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

, который использует указанный конструктор, передавая предоставленные значения из исходных данных.

Тогда это будет IQueryable<MyObject>; Вам не нужно звонить .AsQueryable(). Обратите внимание, что для вашей функции было бы лучше вернуть типизированную форму (IQueryable<MyObject>), чем нетипизированный IQueryable.

8 голосов
/ 20 января 2009

Эта строка синтаксически неверна:

return ticketDetails.AsQueryable()<myObject>;

и следует читать

return ticketDetails.AsQueryable<myObject>();

Кроме того, вы создаете анонимные объекты с select new {, но вы хотите создать myObject экземпляров. Правильная реализация будет выглядеть так:

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, ... создает экземпляр SomeClass и устанавливает свойства для указанных значений. В качестве альтернативы вы можете реализовать конструктор класса myObject и вызвать его в операторе linq с помощью select new myObject(...).

2 голосов
/ 20 января 2009

Как сказал Марк, вы не создаете экземпляры myObject при выполнении запроса. Но, кроме того, вам не нужно приводить его к IQueryable<T>, параметр выбора LINQ вернет IQueryable<T>, если экспликация не приведена к IEnumerable<T>.

Кроме того, будьте осторожны, чтобы ваш DataContext не был утилизирован, прежде чем пытаться получить доступ к возвращаемым данным. Но я заметил, что ваш контекст не сконструирован в методе, будьте осторожны, вы не слишком долго поддерживаете DataContext, это объект единицы работы и не предназначен для того, чтобы его долго открывали.

1 голос
/ 19 марта 2012

уборные, Все это имеет смысл, пока вы возвращаете только одну таблицу, но что, если есть две или более, которые будут возвращены ???

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