дерево выражений лямбда не может содержать нулевой оператор распространения
Вопрос: Цена линии price = co?.price?? 0,
price = co?.price?? 0,
в следующем коде приведена приведенная выше ошибка. но если я удалю ?
от co.?
он отлично работает. Я пытался следовать этому примеру MSDN, где они используются ?
on line select new { person.FirstName, PetName = subpet?.Name?? String.Empty };
select new { person.FirstName, PetName = subpet?.Name?? String.Empty };
Значит, мне нужно понять, когда использовать ?
с ??
и когда не нужно.
Ошибка:
дерево выражений лямбда не может содержать нулевой оператор распространения
public class CustomerOrdersModelView
{
public string CustomerID { get; set; }
public int FY { get; set; }
public float? price { get; set; }
....
....
}
public async Task<IActionResult> ProductAnnualReport(string rpt)
{
var qry = from c in _context.Customers
join ord in _context.Orders
on c.CustomerID equals ord.CustomerID into co
from m in co.DefaultIfEmpty()
select new CustomerOrdersModelView
{
CustomerID = c.CustomerID,
FY = c.FY,
price = co?.price ?? 0,
....
....
};
....
....
}
Ответы
Ответ 1
Пример, который вы цитировали, использует LINQ to Objects, где неявные лямбда-выражения в запросе преобразуются в делегаты... тогда как вы используете EF или аналогичные, с IQueryable<T>
queryies, где лямбда-выражения преобразуются в выражение деревья. Деревья выражений не поддерживают нулевой условный оператор (или кортежи).
Просто сделайте это по-старому:
price = co == null ? 0 : (co.price ?? 0)
(Я считаю, что оператор с нулевым коалесцированием отлично в дереве выражений.)
Ответ 2
Код, на который вы ссылаетесь, использует List<T>
. List<T>
реализует IEnumerable<T>
но не IQueryable<T>
. В этом случае проекция выполняется в памяти и ?.
работает.
Вы используете IQueryable<T>
, который работает по-разному. Для IQueryable<T>
создается представление проекции, и ваш поставщик LINQ решает, что с ним делать во время выполнения. Для соображений обратной совместимости, ?.
не могут быть использованы здесь.
В зависимости от вашего провайдера LINQ вы можете использовать plain .
и до сих пор не получить NullReferenceException
.