2012-03-27 61 views
1

此空检查是我的查询:在LINQ

var entityMerchantVisit = 
    from e in context.MerchantCustomerVisit 
    where e.CustomerId == currentCustGuid 
    group e by 
      new { e.Merchant.Locations.FirstOrDefault().CityId } into mcvGroup 
    orderby mcvGroup.Count() descending 
    select mcvGroup; 

我收到提示

“演员阵容价值型‘的Int32’失败,因为物化值为空”时ê .Merchant.Locations.FirstOrDefault()。CityId为空。

如何检查它是否为空。如果它为空,我想将它分配为(int) 0

+3

仅供参考,在这里被认为是一种很好的形式来标记最有用的答案被接受。如果你的问题已经回答,请这样做! – Ben 2012-04-04 01:52:09

回答

4

像这样的东西可以工作:基于您的评论也许你可以试试下面的(注意括号)

var entityMerchantVisit = 
    from e in context.MerchantCustomerVisit 
    where e.CustomerId == currentCustGuid 
    group e by 
      new { e.Merchant.Locations.FirstorDefault() != null 
        ? e.Merchant.Locations.First().CityId : 0 
       } into mcvGroup 
    orderby mcvGroup.Count() descending 
    select mcvGroup; 

 group e by 
      new { CityID = ((int)e.Merchant.Locations.FirstorDefault() != null 
        ? e.Merchant.Locations.First().CityId : 0) 
       } into mcvGroup 
    orderby mcvGroup.Count() descending 
+0

'.First()'不会返回'null',如果没有项目,它将抛出异常。您应该修改为'.FirstOrDefault()'。 – 2012-03-27 04:12:00

+1

@AlastairPitts啊!哎呦,输入这个太快了。固定。 – gideon 2012-03-27 04:15:49

+0

我试过 group e by new {e.Merchant.Locations.FirstOrDefault()。CityId == null? e.Merchant.Locations.FirstOrDefault()。CityId:0}转换为mcvGroup 但它表示无效的匿名类型成员声明器,它是什么意思? – user777310 2012-03-27 08:09:40

0

使用空合并运算符(? ?)

var entityMerchantVisit = 
from e in context.MerchantCustomerVisit 
where e.CustomerId == currentCustGuid 
group e by 
     new { (e.Merchant.Locations.FirstOrDefault().CityId ?? 0) } into mcvGroup 
orderby mcvGroup.Count() descending 
select mcvGroup; 
+0

这不会改变任何东西。 “NullReferenceException”的原因是OP正尝试从'null'' Location'访问'CityId'。你的代码将抛出完全相同的异常。 – 2012-03-27 04:14:20

+0

你在哪里看到一个NullReferenceException?他没有得到例外。看到这个问题。 http://stackoverflow.com/questions/6864311/the-cast-to-value-type-in​​t32-failed-because-the-materialized-value-is-null。 – Alan 2012-03-27 04:18:51

+0

我的歉意。我不知道LINQ-to-SQL解释器如何处理空合并运算符。我试图删除-1,但该死的东西不会让我:( – 2012-03-27 04:21:35

0

你可以尝试使用Nullable<int>表达:

var entityMerchantVisit = 
    from e in context.MerchantCustomerVisit 
    where e.CustomerId == currentCustGuid 
    group e by new { 
     CityId = e.Merchant.Locations.Any() ? 
      e.Merchant.Locations.First().CityId 
      : default(int?) 
    } into mcvGroup 
    orderby mcvGroup.Count() descending 
    select mcvGroup; 
+0

通过对类型inting的分组,可以保留从'Int32.MinValue'到'Int32.MaxValue'的'CityId'值的完整范围。 – devgeezer 2012-03-27 04:49:55

4

可以使用let语法绑定e.Merchant.Locations.FirstOrDefault()的一系列变量,然后检查了空。这可让您方便地识别没有位置的商家,并为您提供简洁的三元运算符表达式以便启动。

var entityMerchantVisit = 
    from e in context.MerchantCustomerVisit 
    where e.CustomerId == currentCustGuid 
    let location = e.Merchant.Locations.FirstOrDefault() 
    group e by 
      new { CityId = (location == null ? 0 : location.CityId) } into mcvGroup 
    orderby mcvGroup.Count() descending 
    select mcvGroup; 
+0

很好的使用'let'并记住将'CityId'属性名称添加到匿名类型中。 +1 – devgeezer 2012-03-27 04:52:11