5

I am trying to run the following in LINQ

double totalDistance = (from g in db.Logs join 
    h in db.Races on g.raceId equals h.RaceId 
    where g.userId == id select h.distance).Sum();

However get an error:

The cast to value type 'Double' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.

I tried to add on ?? 0; such that:

double totalDistance = (from g in db.Logs join 
    h in db.Races on g.raceId equals h.RaceId 
    where g.userId == id select h.distance).Sum() ?? 0;

As suggested in other posts however this yields an error:

operator '??' cannot be applied to operands double or int

Any suggestions?

EDIT: my model

namespace RacePace.Models
{
public class Race
{
    public int RaceId { get; set; }

    [DisplayName("Race Setting")]
    public string place { get; set; }
    [DisplayName("Distance (km)")]
    public double distance { get; set; }
    [DisplayName("Date")]
    public DateTime date { get; set; }
    [DisplayName("Commencement Time")]
    public DateTime timeStarted { get; set; }
    [DisplayName("Active")]
    public Boolean active { get; set; }
    [DisplayName("Description")]
    public string description { get; set; }
    [DisplayName("Creator")]
    public int UserId { get; set; }
}
}
code4life
  • 15,655
  • 7
  • 50
  • 82
NickP
  • 1,354
  • 1
  • 21
  • 51
  • 2
    Is `distance` nullable? – Mathew Thompson Mar 28 '13 at 15:30
  • Same unfortunately, message then becomes 'Opperator '??' cannot be applied to 'double' or 'floats' – NickP Mar 28 '13 at 15:30
  • Can you show your model? – Alex Mar 28 '13 at 15:30
  • There is something slightly different about this question over the possible duplicate I mentioned above. I think the join might be key (but it would likely only be specific to certain LINQ providers, I think). I'd rescind my close vote if I could. – JayC Mar 28 '13 at 17:04

4 Answers4

2

You should make you distance nullable double in your model to make ?? work. From http://msdn.microsoft.com/en-us/library/ms173224.aspx:

The ?? operator is called the null-coalescing operator and is used to define a default value for nullable value types or reference type

So changing your model to

public double? distance { get; set; }

should make ?? work

Alex
  • 8,827
  • 3
  • 42
  • 58
1

cast them all to double.

double totalDistance = (double)((from g in db.Logs join h in db.Races on g.raceId equals h.RaceId where g.userId == id select h.distance).Sum() ?? 0);

Edit: try to use the double.Parse

var someObject = (from g in db.Logs join h in db.Races on g.raceId equals h.RaceId where g.userId == id select h.distance);
double totalDistance = (someObject !=null)? someObject.Sum() : 0;
Jegan
  • 1,227
  • 9
  • 16
  • Same problem: 'Opperator '??' cannot be applied to 'double' or 'floats' – NickP Mar 28 '13 at 15:33
  • see my edit, if your query returns null then there will not be any sum, and the sum will throw exception. – Jegan Mar 28 '13 at 15:39
  • It still does throw an error? The cast to value type 'Double' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type. – NickP Mar 28 '13 at 15:41
  • Have you tried the edited code, there are no casting in the edited code. – Jegan Mar 28 '13 at 15:43
0

BTW, if any of these isn't the right answer, just please let me know, and I will remove it. No need to get -1 crazy.

Going by Linq query with nullable sum

You could try

double totalDistance = 
   (from g in db.Logs join h in db.Races 
    on g.raceId equals h.RaceId where g.userId == id 
    select h).Sum(x => x.distance) ?? 0;

A better approach in the future might be just to use a nullable until you know what's going on in case there's some weird implicit cast affecting how it compiles. EDIT: it does

double? totalDistanceTemp = 
       (from g in db.Logs join h in db.Races 
        on g.raceId equals h.RaceId where g.userId == id 
        select h).Sum(x => x.distance);
double totalDistance = totalDistanceTemp ?? 0;

if THAT doesn't work, you could try casting to nullables. Mind you, this isn't a literal cast as much as it is a piece of code building an LINQ expression/queryable object which involves a cast expression, and that cast expression ought to get translated to something in your back end. However, I'm not sure that necessarily must be translated.

double? totalDistanceTemp = 
       (from g in db.Logs join h in db.Races 
        on g.raceId equals h.RaceId where g.userId == id 
        select h).Sum(x => (Double?) x.distance);
double totalDistance = totalDistanceTemp ?? 0;

or

double? totalDistanceTemp = 
       (from g in db.Logs join h in db.Races 
        on g.raceId equals h.RaceId where g.userId == id 
        select ((Double?)h.distance )).Sum();
double totalDistance = totalDistanceTemp ?? 0;

And finally if that doesn't work: screw it. get the list from the database, sum it with LINQ to Objects (nullable shouldn't be needed). Use only as last ditch effort. You should not/ought not ever have to do this, but maybe your projects LINQ to whatever provider is just really shoddy or old.

double totalDistance = 
       (from g in db.Logs join h in db.Races 
        on g.raceId equals h.RaceId where g.userId == id 
        select h.distance).AsEnumerable().Sum();

If none of these works, there must be something funny in how that join is translated that either I'm missing or the provider is doing something wacky (or none of the above, of course).

Community
  • 1
  • 1
JayC
  • 7,053
  • 2
  • 25
  • 41
-1

Without access to the rest of your logic it's a bit difficult to determine, but I will give it a go. While I'd personally be more worried about why it comes up null in the first place, if null is an expected result then you might be able to use a nullable type. You can find more information about them on MSDN. If you DO use a nullable type you will also want to check for value before continuing on past that double totalDistance line. This is explained in the MSDN link.

Kerfuffle
  • 176
  • 11