ksg
ksg

Reputation: 4067

Sequence contains no elements Error

My dbstructure is as follows

StudentRegistrationTable

Id      Name     
5       Sachin 

StudentReceiptTable

Id      StudRegId     Fee    ST     Total      Status     DueDate 
1         5           873   127    1000         1        01/05/2016
2         5           873   127    2000         1        01/15/2016
3         5           873   127    3000         0        01/25/2016
4         5           873   127    4000         0        01/28/2016
5         5           873   127    5000         0        01/30/2016

Status indicates the payment mode.Status 1 indicates student has paid the receipt and 0 indicates the unpaid receipt

Query

  _dTableReg = _db.StudentRegistrations
                .AsEnumerable()
                .Where(r => (..condition))
                .Select(r => new RegistraionVM.RegDataTable
                 {    
                    ...
                    ...                      
                    NextDueAmount = r.StudentReceipts.
                                     Where(rc => rc.Status == false)
                                     .First().Total.ToString(),
                    NextDueDate = r.StudentReceipts.
                                    Where(rc => rc.Status == false)
                                    .First().DueDate.Date.ToString('dd/MM/yyyy')                                     
                }).OrderByDescending(r => r.RegistrationID).ToList();

The above query returns the first unpaid amount and date(3000 & 01/25/2016).

The problem arises when student has paid all the receipt (ie status will be set to 1) and i am getting Sequence contains no elements errror.In that case I want to return FULL PAID in both NextDueAmount and NexDueDate

RegDataTable Class

    public class RegDataTable
    {       
        ...
        ...     
        public string NextDueAmount { get; set; }
        public string NextDueDate { get; set; }           

    }      

Upvotes: 0

Views: 1497

Answers (1)

user3559349
user3559349

Reputation:

Your use of .First() will throw the error is the collection of StudentReceipt returns no items (i.e. when the Status of all items is true). You need to use .FirstOrDefault() and then check if the value is null, and if not then access the Total and DueDate properties.

This could make you controller code unnecessarily complex (and your also accessing the database twice to get the collection) so I suggest you use a view model (if its not already) with additional read only properties to return the results

public class RegDataTableVM
{
  ....
  public StudentReceipt Receipt { get; set; }
  public string NextDueAmount
  {
    get { return Receipt == null ? "FULL PAID" ? Receipt.Total.ToString() }
  }
  public string NextDueDate 
  {
    get { return Receipt == null ? "FULL PAID" ? Receipt.DueDate.ToString("dd/MM/yyyy") }
  }

and modify the query to

_dTableReg = _db.StudentRegistrations
  .Where(r => (..condition))
  .Select(r => new RegDataTableVM
  {    
    ...
    ...
    Receipt = r.StudentReceipts.Where(rc => rc.Status == false).FirstOrDefault()                                     
  }).OrderByDescending(r => r.RegistrationID).ToList();

Side note: If your using DisplayFor() to generate the html, you can also make use of the DisplayFormatAttribute

[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", NullDisplayText = "FULL PAID"
public DateTime? NextDueDate
{
  get { return return Receipt == null ? null ? Receipt.DueDate }
}

Upvotes: 2

Related Questions