дерево выражений lambda не может содержать оператор распространения null

вопрос: строку price = co?.price ?? 0, в следующем коде дает мне вышеуказанную ошибку. но если я удалю ? С co.? он работает нормально. Я пытался следовать этот пример MSDN, где они с помощью ? on line select new { person.FirstName, PetName = subpet?.Name ?? String.Empty }; Итак, кажется, мне нужно понять, когда использовать ? С ?? а когда нет.

:

дерево выражений lambda не может содержать нулевое распространение оператор

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

2 ответов


в Примере, который вы цитировали, используется LINQ to Objects, где неявные лямбда-выражения в запросе преобразуются в представители... в то время как вы используете EF или аналогичный, с IQueryable<T> queryies, где лямбда-выражения преобразуются в выражение деревьев. Деревья выражений не поддерживают нулевой условный оператор (или кортежи).

просто сделайте это по-старому:

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

(Я считаю, что оператор null-coalescing в порядке в дереве выражений.)


код, на который вы ссылаетесь, использует List<T>. List<T> осуществляет IEnumerable<T> а не IQueryable<T>. В этом случае, проекция выполняется в памяти и ?. строительство.

вы используете какой-то IQueryable<T>, который работает совсем по-другому. Для IQueryable<T>, создается представление проекции, и ваш поставщик LINQ решает, что с ним делать во время выполнения. По соображениям обратной совместимости,?. здесь нельзя использовать.

в зависимости от вашего поставщика LINQ, вы можете быть возможность использования plain . и все равно не получишь никакого NullReferenceException.