Создание IQueryable на основе параметров метода

У меня есть метод API, подобный приведенному ниже.

Можно ли добавить IQueryable, чтобы в окончательном запросе был список элементов для выполнения оператора where, или мне следует использовать свойство SqlQuery и создать необработанную строку SQL.

    public IEnumerable<Message> GetMessagesFromApi(DateTime? dateFrom = null, DateTime? dateTo = null, int flag = -1, int messageType = 1, bool media =false)
    {
        if (dateFrom == null)
            dateFrom = DateTime.MinValue;

        if (dateTo == null)
            dateTo = DateTime.MaxValue;

        IQueryable<Message> query = null;


        query = db.Messages.Where(x => x.Created >= dateFrom && x.Created <= dateTo);


        if (flag >= 0)
        {
            //Append the where statement on dates to now include Flag
            query = query.Where(x => x.Flag == flag);
        }

       //Here it should execute against Where date >= and date <= and flag = 1
    }

person Jon    schedule 28.03.2013    source источник


Ответы (1)


Можно ли добавить IQueryable, чтобы в окончательном запросе был список элементов для выполнения оператора where.

да. Ваш код должен работать нормально. Вам просто нужно выполнить это, если вы хотите построить IEnumerable<Message> для результата.

//Here it should execute against Where date >= and date <= and flag = 1
return query.ToList();

Обратите внимание, что вы можете использовать AsEnumerable() или даже просто вернуть query напрямую (поскольку IQueryable<T> реализует IEnumerable<T>), но это вызовет проблемы, если пользователь перечислит ваши результаты более одного раза, поскольку каждое перечисление попадет в БД.

Я бы лично написал это так:

public IEnumerable<Message> GetMessagesFromApi(DateTime? dateFrom = null, DateTime? dateTo = null, int flag = -1, int messageType = 1, bool media =false)
{
    IQueryable<Message> query = db.Messages;

    if(dateFrom.HasValue)
        query = query.Where(x => x.Created >= dateFrom);
    if(dateTo.HasValue)
        query = query.Where(x => x.Created <= dateTo);
    if(flag >= 0)
        query = query.Where(x => x.Flag == flag);
    // others as needed, such as media...

    return query.ToList();
}
person Reed Copsey    schedule 28.03.2013
comment
Я использую EF, могу ли я использовать return AsEnumerable () - person Jon; 28.03.2013
comment
@Jon Да, хотя с AsEnumerable(), если вызывающий абонент перечислит его дважды, он дважды попадет в БД ... - person Reed Copsey; 28.03.2013
comment
ах хорошо, спасибо, тогда вернем список. Глядя на код, кажется, что запрос будет перезаписываться каждый раз, когда он не добавлен. - person Jon; 28.03.2013
comment
@Jon Посмотрите на мое обновление - query станет новым запросом, к которому будет добавлено предложение Where к старому, поскольку он выполняет query = query.Where .. - person Reed Copsey; 28.03.2013