0

I am attempting to use a Select statement in my Asp.Net app. Rather than filter the excluded fields out, it sets them to Null or 0. Is this by design or something I'm doing wrong? Code is below:

        public async Task<ActionResult<IEnumerable<Attendance>>> GetAttendanceTopYear(string Year)
        {
            return await _context.Attendance.Select(x => new Attendance { Name = x.Name, Year = x.Year, Present = x.Present }).Where(x => x.Year == Year).OrderByDescending(x => x.Present).ToListAsync();
        }

Any help is appreciated

1
  • Weird, why do you put a Where after the Select? Commented Nov 5, 2020 at 12:49

1 Answer 1

2

Rather than filter the excluded fields out, it sets them to Null or 0. Is this by design or something I'm doing wrong?

That's what C# does if you don't populate fields/properties on declared types with any values; they acquire a default value for the type, usually null or 0. You can't "get rid" of fields on Attendance objects simply by not mentioning them; an Attendance instance always has all the fields declared in the class, so if the class def dictates it has an int FineForNotAttending property, and you make a new Attandance object and never set a value for FineForNotAttending then it defaults to 0 (the default value for an int)

I think you might be copying some code from elsewhere that uses an anoynmous type, and in that case the "excluded fields" really are missing, because they aren't present on the type object the compiler generates

Compare:

_context.Attendance.Select(x => new Attendance { Name = x.Name, Year = x.Year, Present = x.Present })

//might produce an Attendance list like:
[
  {
    "Name": "Jonny",
    "Year": 2020,
    "Month:" 0,
    "Day": 0,
    "Present": true,
    "FineForNotAttending": 0,
    "ReasonForNotAttending": null
  }
]   

_context.Attendance.Select(x => new { Name = x.Name, Year = x.Year, Present = x.Present })

//might produce a list of anonymous types like:
[
  {
    "Name": "Jonny",
    "Year": 2020,
    "Present": true
  }
]

The only difference between he top and bottom code is the lack of Attendance between new and {. The bottom code is an anon type generated by the compiler having only those props you mentioned

Edit: to be clear, you can't just change your top code into the bottom and expect it to work. You've declared that the method returns an IEnumerable<Attendance> - Attendance being a class you created. You cannot simply return an anonymous type (a class the compiler wrote for you that has some properties of an Attendance but not others) because there isn't any kind of relationship between Attendance and some anonymous type the compiler created.

For the same reason that you cannot say:

public Dog GetDog(){
  return new Car(); //method returns a Dog, cannot return a Car
}

You cannot say:

public IEnumerable<Dog> GetDog(){
  return dogs.First().Select(d => new { d.Name, d.Breed }); //returns an anon type having some properties that a Dog also has
}

..because the returned type is not a Dog, it's a new anonymous type that is a pair of strings. If you returned a new Dog with only the name and breed set, then NumberOfLegs, CollarNumber, OwnerName etc would all be null/0 but they would still exist (because it's not a Dog if they don't)

Sign up to request clarification or add additional context in comments.

2 Comments

Changing to the second block of code returns an error Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type: string Name, string Year, decimal Present>>' to 'Microsoft.AspNetCore.Mvc.ActionResult<System.Collections.Generic.IEnumerable<StudentAttendance.Models.Attendance>>'
Yes, it wasn't the intention to tell you what you do need to do (because it isn't clear), it was merely to suggest to you a) where your expectation mismatched reality and b) how your expectation and reality could be aligned. Your method returns an IEnumerable<Attendance> so you cannot return an IEnumerable<anonymoustypex> - added some clarity on this

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.