1

This is my query:

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;

I'm getting error

"The cast to value type 'Int32' failed because the materialized value is null" when e.Merchant.Locations.FirstOrDefault().CityId is null.

How do I check if it's null before hand. I would like to assign it as (int) 0 , if it is null.

gideon
  • 19,329
  • 11
  • 72
  • 113
user777310
  • 215
  • 3
  • 14
  • 3
    FYI, it's considered good form here to mark the most helpful answer as accepted. If your question has been answered, please do so! – Ben Apr 04 '12 at 01:52

4 Answers4

4

Something like this could work:

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;

Based on your comment you could maybe try the following (note the parenthesis) :

     group e by  
           new { CityID = ((int)e.Merchant.Locations.FirstorDefault() != null 
                  ? e.Merchant.Locations.First().CityId : 0)
               } into mcvGroup
     orderby mcvGroup.Count() descending
gideon
  • 19,329
  • 11
  • 72
  • 113
  • `.First()` will not return `null`, it will thrown an exception if there is no item.. You should amend this to `.FirstOrDefault()`. – Alastair Pitts Mar 27 '12 at 04:12
  • 1
    @AlastairPitts ah! whoops, typed this too quickly. Fixed. – gideon Mar 27 '12 at 04:15
  • I tried this group e by new { e.Merchant.Locations.FirstOrDefault().CityId == null ? e.Merchant.Locations.FirstOrDefault().CityId : 0 } into mcvGroup but it says invalid anonymous type member declarator , what does it means ? – user777310 Mar 27 '12 at 08:09
  • Ok another way of doing this is , how do I check the result of "The cast to value type 'Int32' failed because the materialized value is null" . It is not an exception and not actually null . Simply said , how do I check var entityMerchantVisit when there is this case . – user777310 Mar 27 '12 at 08:37
4

You can use the let syntax to bind e.Merchant.Locations.FirstOrDefault() to a range variable, and then check that for null. This lets you conveniently identify merchants without locations, and gives you a concise ternary-operator expression to boot.

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;
Ben
  • 6,023
  • 1
  • 25
  • 40
0

Use the null coalescing operator (??)

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;
Alan
  • 45,915
  • 17
  • 113
  • 134
  • this doesn't change anything. The reason for the `NullReferenceException` is that the OP is trying to access the `CityId` off a `null` `Location`. Your code will throw exactly the same exception. – Alastair Pitts Mar 27 '12 at 04:14
  • Where do you see a NullReferenceException? He's not getting an exception. See this question. http://stackoverflow.com/questions/6864311/the-cast-to-value-type-int32-failed-because-the-materialized-value-is-null. – Alan Mar 27 '12 at 04:18
  • My apologies. I was not aware of how the LINQ-to-SQL interpreter thingo deals with the null coalescing operator. I tried to remove the -1 but the damn thing won't let me :( – Alastair Pitts Mar 27 '12 at 04:21
  • same , getting " invalid anonymous type member declarator" with this – user777310 Mar 27 '12 at 08:28
  • Ok another way of doing this is , how do I check the result of "The cast to value type 'Int32' failed because the materialized value is null" . It is not an exception and not actually null . Simply said , how do I check var entityMerchantVisit when there is this case – user777310 Mar 27 '12 at 08:38
0

You could try using a Nullable<int> expression:

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;
devgeezer
  • 4,159
  • 1
  • 20
  • 26
  • By grouping-by an `int?` type, the complete range of values of `CityId` - from `Int32.MinValue` to `Int32.MaxValue` is retained. – devgeezer Mar 27 '12 at 04:49