un árbol de expresiones lambda no puede contener un operador de propagación nulo


Pregunta: La línea price = co?.price ?? 0, en el siguiente código me da el error anterior. pero si elimino ? de co.? funciona bien. Estaba tratando de seguir este ejemplo de MSDN donde están usando ? en línea select new { person.FirstName, PetName = subpet?.Name ?? String.Empty }; Así que, parece que necesito entender cuándo usar ? con ?? y cuándo no hacerlo.

Error:

Un árbol de expresiones lambda no puede contener un operador de propagación nulo

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,
                  ....
                  ....
              };
    ....
    ....
 }
Author: Filburt, 2017-06-21

2 answers

El ejemplo que estaba citando usa LINQ para Objetos, donde las expresiones lambda implícitas en la consulta se convierten en delegados... mientras que está usando EF o similar, con IQueryable<T> consultas, donde las expresiones lambda se convierten en árboles de expresiones. Los árboles de expresión no admiten el operador condicional nulo (o tuplas).

Simplemente hazlo de la manera antigua:

price = co == null ? 0 : (co.price ?? 0)

(Creo que el operador null-coalescing está bien en un árbol de expresiones.)

 51
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-21 16:19:47

El código al que enlazas usa List<T>. List<T> implementa IEnumerable<T> pero no IQueryable<T>. En ese caso, la proyección se ejecuta en memoria y ?. funciona.

Estás usando algunos IQueryable<T>, que funcionan de manera muy diferente. Para IQueryable<T>, se crea una representación de la proyección, y su proveedor de LINQ decide qué hacer con ella en tiempo de ejecución. Por razones de compatibilidad con versiones anteriores, ?. no se puede usar aquí.

Dependiendo de su proveedor de LINQ, es posible que pueda usar . sin obtener cualquier NullReferenceException.

 4
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-21 16:24:13