Yiyi Chen Yiyi Chen - 17 days ago 6
C# Question

Getting null exception with Linq Max()

I'm working with EF and a database that uses a common lookup design with two tables (T_LookupCategories and T_LookupValues) and a SequenceNumber column.
Now I'm trying to write a method that return the max sequence number for the lookup value of a specific category but a continue to get the exeption

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


The code is this:

public int GetNextSequenceNumber(T_LookupCategories lookupCategory)
{
IList<T_LookupValues> lookupValues = Context.T_LookupValues
.Where(x => x.ID_LookupCategory == lookupCategory.ID_LookupCategory)
.ToList();

return lookupValues == null ? 1 : lookupValues.Max(x => x.SequenceNumber) + 1;
}


Why? I don't understand.
Is correct how I check for null values?

EDIT

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace GIE.ITTeamSite.Data.DAL.Entities
{
using System;
using System.Collections.Generic;

public partial class T_LookupCategories
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public T_LookupCategories()
{
this.T_LookupValues = new HashSet<T_LookupValues>();
}

public int ID_LookupCategory { get; set; }
public string LookupCategory { get; set; }

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_LookupValues> T_LookupValues { get; set; }
}
}

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace GIE.ITTeamSite.Data.DAL.Entities
{
using System;
using System.Collections.Generic;

public partial class T_LookupValues
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public T_LookupValues()
{
this.T_Phases = new HashSet<T_Phases>();
this.T_Phases1 = new HashSet<T_Phases>();
this.T_Phases2 = new HashSet<T_Phases>();
this.T_Projects = new HashSet<T_Projects>();
this.T_Projects1 = new HashSet<T_Projects>();
this.T_Projects2 = new HashSet<T_Projects>();
this.T_Projects3 = new HashSet<T_Projects>();
this.T_Projects4 = new HashSet<T_Projects>();
this.T_Projects5 = new HashSet<T_Projects>();
this.T_Projects6 = new HashSet<T_Projects>();
this.T_Projects7 = new HashSet<T_Projects>();
this.T_Tasks = new HashSet<T_Tasks>();
this.T_Tasks1 = new HashSet<T_Tasks>();
this.T_Tasks2 = new HashSet<T_Tasks>();
}

public int ID_LookupValue { get; set; }
public int ID_LookupCategory { get; set; }
public string LookupValue { get; set; }
public int SequenceNumber { get; set; }

public virtual T_LookupCategories T_LookupCategories { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Phases> T_Phases { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Phases> T_Phases1 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Phases> T_Phases2 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Projects> T_Projects { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Projects> T_Projects1 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Projects> T_Projects2 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Projects> T_Projects3 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Projects> T_Projects4 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Projects> T_Projects5 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Projects> T_Projects6 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Projects> T_Projects7 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Tasks> T_Tasks { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Tasks> T_Tasks1 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<T_Tasks> T_Tasks2 { get; set; }
}
}

Answer

you should probably:

return lookupValues == null ? 1 : (lookupValues.Max(x => (int?)x.SequenceNumber) ?? 0) + 1;

or as you materialize the List

return lookupValues == null ? 1 : 
    lookupValues.Count == 0 ? 1 :
        lookupValues.Max(x => x.SequenceNumber) + 1;

the point is most certainly that x.SequenceNumber is an int.

Comments