0

i have a star_tbl . i wanna make starpart in my web site. my cod:

public int StarProduct(int id_Product)
{
  return Convert.ToInt32(db
    .tbl_satar_Product
    .Where(p => p.Id_Product == id_Product && p.star != null)
    .Average(s => s.star));
}

but t shows this 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.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
niknaz
  • 47
  • 2
  • 11

6 Answers6

1

It sounds to me like your database is inconsistent with your model definition. That is, you have defined your model in a way that is different from your databases actual definition.

In particular, it sounds like star may be a nullable int in the database, but you have defined it as an int in your model. You need to either change your database, or change your model to correct this.

Your p.star != null statement makes no sense if star is not a nullable int, since it should not be possible for star to be null unless your database is defined differently.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
0

And what about this?

public int StarProduct(int id_Product)
{
  return Convert.ToInt32(db
    .tbl_satar_Product
    .Where(p => p.Id_Product == id_Product && p.star.HasValue)
    .Average(s => s.star.Value));
}
oddparity
  • 438
  • 5
  • 14
0

It appears the Average part is returning a null (as a double that cannot be converted to int. Solutions:

  • Change the return type to int?
  • Split the method into separate components that you can then debug separately:

    var items = Convert.ToInt32(db.tbl_satar_Product.Where(p => p.Id_Product == id_Product && p.star.HasValue)

and then

return ((int)items.Average(s => s.star)) ?? 0

You can then check each component separately.

Peter Smith
  • 5,528
  • 8
  • 51
  • 77
0

I suppose you have a class similar to this:

class TblSatarProduct
{
   public int Id_Product {get;set;}
   public int star {get;set;}
}

And tbl_satar_Product is a instance of this. Now you can do this in your method public int StarProduct(int id_Product):

First get list (IEnumerable):

var list = db
    .tbl_satar_Product
    .Where(p => p.Id_Product == id_Product)

 if (list == null)
 {
     return 0; // or default value 
 }

If star is int you don't need && p.star != null, if you need check if have a value in star, maybe you need to change it to int? in this case you could use != null.

Then, you get the average:

 double average = list.Average(s => s.star);

 if (average == null)
 {
     return 0; // or default value 
 }

Maybe in this point, you can return double type, and then who call method StarProduct will have to take care of the conversion.

Finally:

try {
    int averageInt = Convert.ToInt32(average);
    return averageInt;
}
catch (OverflowException ex)  
{
    //outside the range of the Int32 type
    //check what do you do?
}   

Info
Enumerable.Average (Método) (IEnumerable)
Casting and Type Conversions (C# Programming Guide)

andres descalzo
  • 14,887
  • 13
  • 64
  • 115
0

I suppose you have 0 records in your query and that is why you cannot perform average.

Tomas Kubes
  • 23,880
  • 18
  • 111
  • 148
0

Nullable Field: If the calculating field is nullable then no need to do anything special. Just use Average as it is, like below:

var avg = expression.Average(x => x.Star);

Here, the average is nullable (int?). If you make it not nullable then use the null coalescing operator and set a default value 0(zero), like below:

var avg = expression.Average(x => x.Star) ?? 0;

Not Nullable Field: But, if the calculating field is not nullable, then you need to cast nullable first for average, like this below:

var avg = expression.Average(x => (int?)x.Star);

Also here, the average is nullable (double?). If you make it not nullable then use the null coalescing operator, like below:

var avg = expression.Average(x => (int?)x.Star)?? 0;
Rousonur Jaman
  • 1,183
  • 14
  • 19