Что не так с этим утверждением ниже

Что не так с этим утверждением ниже? Я получаю «ожидаемый» при запуске в LinqPad с языковой настройкой «Выражение C#».

from p in Products where p.UnitPrice > 50 select new {p.ProductID };

Теперь похоже, что если я назначу его любому var; Я не получаю никакой ошибки. Но что меня смущает, так это то, что приведенный ниже оператор отлично работает и возвращает мне результаты, хотя я не присваиваю его какой-либо переменной. Любые идеи?

    from p in Products
let spanishOrders = p.OrderDetails.Where ( o=> o.Order.ShipCountry == "Spain")
where spanishOrders.Any()
group new
{
    p.ProductName,
    Orders = spanishOrders.Count(),
    spanishOrders
}
by p.Category.CategoryName

РЕДАКТИРОВАТЬ: На самом деле это было плохо, я не мог запустить второй пример, не назначив его переменной.


person Silverlight Student    schedule 04.11.2011    source источник
comment
Можете ли вы опубликовать остальную часть кода, пожалуйста?   -  person MGZero    schedule 04.11.2011
comment
Код находится в приложении или вы на самом деле используете LINQ Pad (видел тег linqpad... это может иметь значение)?   -  person Justin Niessner    schedule 04.11.2011
comment
Каков ваш язык в LINQPad?   -  person mwilson    schedule 04.11.2011
comment
обновленный вопрос с более подробной информацией   -  person Silverlight Student    schedule 04.11.2011
comment
Если вы находитесь в режиме языка C# Expression, вы должны убрать точку с запятой в первом примере. Смотрите мой пост ниже.   -  person Alex Moore    schedule 04.11.2011
comment
Я получил '; ожидается», если я попытаюсь запустить второй пример как оператор C#.   -  person Alex Moore    schedule 04.11.2011
comment
Какую версию LINQPad вы используете? 4.31 Бесплатная версия?   -  person Alex Moore    schedule 04.11.2011
comment
@Alex: Да, это бесплатная версия 4.31.   -  person Silverlight Student    schedule 04.11.2011


Ответы (7)


Выражения запроса LINQ не являются допустимыми операторами C#. Вам нужно использовать выражение в действительном операторе.

Например, вы можете использовать выражение в правой части оператора присваивания:

var expensiveProductIds = from p in Products
                          where p.UnitPrice > 50 
                          select new { p.ProductID };

Мне кажется, что вы действительно не понимаете, что такое LINQ. Что вы ожидали от открытого выражения запроса?

EDIT: взгляните на ответ Алекса Мура о том, как заставить это работать в LINQPad.

Кстати, вот способ получить результаты запроса, записанные на консоль, если вы все еще хотите придерживаться режима «Высказывания C#»:

var expensiveProductIds = from p in Products
                          where p.UnitPrice > 50 
                          select new { p.ProductID };

expensiveProductIds.Dump();
person Ani    schedule 04.11.2011
comment
LINQPAD имеет режим Expression, который выполняет операторы так, как он их написал (без точки с запятой в конце). Я предполагаю, что именно так он/она ожидал, что это сработает. - person Marc; 04.11.2011
comment
Он/она пробует выражение в LINQPad, а не в C# как выражение. - person Alex Moore; 04.11.2011
comment
LINQPAD имеет комбинацию языков, я выбрал оттуда статус С#. Просто для ясности, есть еще один вариант C # Expression, но это НЕ то, что я использую в этом случае. - person Silverlight Student; 04.11.2011
comment
@Marc: режим операторов LINQPad, как и компилятор C#, не принимает выражения запросов, пытающиеся маскироваться под операторы (заканчивая их точкой с запятой). - person Ani; 04.11.2011
comment
@Ani: Да, это правда, я совершенно новичок в Linq и изо всех сил пытаюсь пройти через начальный горб. Спасибо за вашу помощь. - person Silverlight Student; 04.11.2011

Если вы используете «Выражение C#» в качестве языка в раскрывающемся списке языка LinqPad, вы должны убрать точку с запятой, потому что это просто выражение:

from p in Products where p.UnitPrice > 50 select new {p.ProductID }

Если вы используете «оператор(ы) C#» в качестве языка, вам придется написать его как обычный код C#:

var x = (from p in Products where p.UnitPrice > 50 select new {p.ProductID });

LINQPad позволяет тестировать оба способа, потому что некоторые запросы становятся проще, когда операторы не мешают друг другу.

person Alex Moore    schedule 04.11.2011
comment
Я добавил рассматриваемый пример, в котором я могу запустить его как статус С#, не назначая его обратно переменной - person Silverlight Student; 04.11.2011
comment
Я получил '; ожидается», если я попытаюсь запустить второй пример как оператор C#. - person Alex Moore; 04.11.2011

Попробуйте присвоить результат переменной.

var v = from p in Products where p.UnitPrice > 50 select new {p.ProductID }; 
person Purplegoldfish    schedule 04.11.2011

Ваш код не является допустимым оператором C#.

Либо присвойте значение вашего выражения переменной:

var q = from p in ... ;

Или удалите точку с запятой в конце и измените язык на Выражение C#.

person Jan    schedule 04.11.2011

Вам нужно присвоить его чему-то.

var productIds = from p in Products where p.UnitPrice > 50 select new {p.ProductID };
person Adam Barney    schedule 04.11.2011

Единственное, что мне кажется странным, это то, что в вашем новом анонимном объекте вы не присваиваете ProductID свойству, но я думаю, что это на самом деле не требуется (я только что попробовал).

from p in Products where p.UnitPrice > 50 select new { ProductID = p.ProductID };

EDIT: из-за комментариев я понимаю, что это не даст ничего полезного для решения проблемы ОП.

person Cᴏʀʏ    schedule 04.11.2011
comment
Вам не нужно указывать имя свойства, если вы назначаете поле или свойство и хотите сохранить это имя. Действительно очень удобно! - person leppie; 04.11.2011
comment
new { p.ProductID } и new { ProductID = p.ProductID } создадут один и тот же анонимный тип. - person cadrell0; 04.11.2011
comment
@cadrell0: Не знал этого (обновил мой ответ)! Думаю, мне просто всегда нравится быть явным с этими проклятыми анонимными типами :) - person Cᴏʀʏ; 04.11.2011
comment
Раньше я всегда был откровенным, потом у меня появился ReSharper, и он начал меня ругать. - person cadrell0; 04.11.2011

вы пытаетесь выбрать после того, как его назначили так. поэтому вы должны использовать что-то вроде этого

from p in Products where p.UnitPrice > 50 select 
                                                new { 
                                                      ProductID = p.ProductID 
                                                    };
person Hari Gillala    schedule 04.11.2011
comment
Это тот же код, за исключением того, что у вас есть несколько новых строк. И избыточное имя свойства в вашем анонимном типе. - person cadrell0; 04.11.2011