2017-06-21 253 views
9

问题:下面的代码行price = co?.price ?? 0,给我上面的错误。但如果我从co.?删除?它工作正常。我试图按照this MSDN example他们在哪里使用?在线select new { person.FirstName, PetName = subpet?.Name ?? String.Empty };所以,我似乎需要了解何时使用???和什么时候不使用。表达式树lambda可能不包含空传播运算符

错误

表达式树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, 
        .... 
        .... 
       }; 
    .... 
    .... 
} 
+0

请发布错误... –

+0

我希望C#支持这个人! – nawfal

回答

21

你是从引用的示例使用LINQ到对象,其中,所述隐式lambda表达式在查询中转换成代表 ...而您使用的是EF或类似的,IQueryable<T>查询,其中lambda表达式被转换成表达树。表达式树不支持空条件运算符(或元组)。

只是做旧的方式:(我相信空合并运算符是一个表达式树罚款)

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

+0

谢谢。你回答我的[this](https://stackoverflow.com/q/44681042/1232087)'SO'问题。 – nam

3

您链接到应用List<T>的代码。 List<T>执行IEnumerable<T>但不是IQueryable<T>。在这种情况下,投影在内存中执行并?.工作。

您正在使用一些IQueryable<T>,其工作原理有所不同。对于IQueryable<T>,投影的表示被创建,并且您的LINQ提供者决定在运行时如何处理它。出于向后兼容性的原因,此处不能使用?.

根据您的LINQ提供商,您可以使用普通的.,但仍未获得任何NullReferenceException

+0

您回答了我的[this](https://stackoverflow.com/q/44681042/1232087)'SO'问题。谢谢。 – nam

+0

@ hvd你能解释为什么这是向后兼容性所必需的吗? – jag

+1

@jag在引入'?.'之前已经创建的所有LINQ提供者都不会准备好以任何合理的方式处理'。.'。 – hvd

相关问题