How do I use a Lambda Select to return a specific data type?

I have the following States table with a list of the US States.  I want a method that will return the list of states but just the State Abbreviation and State Name so it can be used in a drop down.  I am having a problem with formatting my lambda expression to give me what I want.

Here is what I have so far:

State Table definition generated by Entity Framework model
namespace CoreDataClass.Model
{
    using System;
    using System.Collections.Generic;
    
    public partial class State
    {
        public int StateId { get; set; }
        public string StateName { get; set; }
        public string StateAbbr { get; set; }
        public int DrcStateNbr { get; set; }
        public int UwStateId { get; set; }
    }
}

Open in new window


Here is my In-Memory representation of the State table to be used with Unit Testing:
namespace CoreDataTests.Repository
{
    class InMemoryCoreDataRepository : ICoreDataRepository
    {
        private List<State> _dbStatesTBL = new List<State>();
        private List<qpIndex> _dbqpIndexesTBL = new List<qpIndex>();

        public void Add(State recordToAdd)
        {
            _dbStatesTBL.Add(recordToAdd);
        }

        public int SaveChanges()
        {
            return 1;
        }

        public List<StateDropdown> GetStates()
        {
            var dbrecords = _dbStatesTBL.Select(st => new { StateAbbr = st.StateAbbr, StateName = st.StateName });
            // Throw error if no records are returned - this table should have records
            if (dbrecords == null || dbrecords.Count() == 0)
                throw new ApplicationException("States Table is empty");
            return dbrecords as List<StateDropdown>;
        }
    }
}

Open in new window


Unit Test:  (PopulateTable creates entries in the In Memory table)
        [TestMethod]
        public void GetStates_Returns_StateName_And_State_Abbreviation_In_StateName_Alphabetical_Order()
        {
            // Arrange
            InMemoryCoreDataRepository repository = PopulateTable();
            CoreData sut = new CoreData(repository);

            // Act
            var result = sut.GetStates();

            // Assert
            Assert.IsInstanceOfType(result, typeof(List<StateDropdown>));
            Assert.AreEqual(51, result.Count());                            // list contains Washington, DC
            StateDropdown firstState = result.ElementAt(0);
            StateDropdown lastState = result.ElementAt(50);
            Assert.AreEqual("ALASKA", firstState);
            Assert.AreEqual("WYOMING", lastState);   
        }

Open in new window


Unit Test fails with the following Error Message:
Assert.IsInstanceOfType failed.  Expected type:<System.Collections.Generic.List`1[CoreDataClass.Model.StateDropdown]>. Actual type:<(null)>.

When debugging, I get 51 when I print dbrecords.Count() which is what I am expecting (list includes Washington, DC).

I get the error when I try and Assert that the result is of type List<StateDropdown>.  Can anyone tell me what I am doing wrong?  Any help is greatly appreciated!
dyaroshAsked:
Who is Participating?
 
BeartlaoiConnect With a Mentor Commented:
You need to fill-in the get and set members like this:
public string StateAbbr {
get { return this.StateAbbr; }
set { this.StateAbbr = value; }
}
public string StateName { 
get { return this.StateName; }
set { this.StateName= value; }
}

Open in new window

0
 
BeartlaoiCommented:
At the bottom of GetStates() you have
return dbrecords as List<StateDropdown>;
So you are casting a List<State> to List<StateDropdown>
How is StateDropdown defined?  Are you missing something that allows the cast to succeed?
0
 
dyaroshAuthor Commented:
Here is how StateDropdown is defined:
    public partial class StateDropdown
    {
        string StateAbbr;
        string StateName;
    }

Open in new window

0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
BeartlaoiCommented:
Thats partial, is there more to it?  
Anyway to help debug where I think the problem is change the last line in GetStates() from
return dbrecords as List<StateDropdown>;
to
List<StateDropdown> retVal = dbrecords as List<StateDropdown>;
if (retVal == null)
                throw new ApplicationException("Cast returned null");
return retVal;
0
 
dyaroshAuthor Commented:
I made the modifications you suggested and retVal is null.  dbrecords.Count() still returns 51.
0
 
dyaroshAuthor Commented:
Here is some debug output:

>? dbrecords.ElementAt(0)
{ StateAbbr = "AK", StateName = "ALASKA" }
    StateAbbr: "AK"
    StateName: "ALASKA"
>
0
 
Fernando SotoRetiredCommented:
Hi dyarosh;

The StateDropdown class needs to have two public properties in order for the Linq query to fill them. I have also modified the Linq query itself.

public List<StateDropdown> GetStates()
{
    // I have modified the next line of code.
    var dbrecords = _dbStatesTBL.Select(st => new StateDropdown { StateAbbr = st.StateAbbr, StateName = st.StateName });
    
    // Throw error if no records are returned - this table should have records
    if (dbrecords == null || dbrecords.Count() == 0)
        throw new ApplicationException("States Table is empty");
        
    // I modified the next line of code.    
    return dbrecords.ToList();
}

// This class needs to have these two public properties
// So that the Linq query can fill them 
public partial class StateDropdown
{
    public string StateAbbr { get; set; }
    public string StateName { get; set; }
}

Open in new window

0
 
dyaroshAuthor Commented:
Here is my StateDropdown definition:
    public partial class StateDropdown
    {
        public string StateAbbr { get; set; }
        public string StateName { get; set; }
    }

Open in new window


Here is the change I made in the GetStates method:
var dbrecords = _dbStatesTBL.Select(st => new StateDropdown { StateAbbr = st.StateAbbr, StateName = st.StateName }).OrderBy(st => st.StateName).ToList();

Open in new window


I am getting the following errors:

'CoreDataClass.Model.StateDropdown' does not contain a definition for 'StateAbbr'
'CoreDataClass.Model.StateDropdown' does not contain a definition for 'StateName'

If I do the following I can access StateAbbr and StateName in StateDropdown:
StateDropdown std = new StateDropdown();
std.StateAbbr = "PA";
std.StateName = "Pennsylvania";

Open in new window


Any thoughts as to what I am doing wrong?
0
 
Fernando SotoRetiredCommented:
Can you post the schema for the object _dbStatesTBL, please.
0
 
dyaroshAuthor Commented:
I had to make the following changes because my unit tests were crashing (not failing but crashing) when I used your implementation.  Not sure why but implementing the private properties solved the problem.  Thank you for your help!


private string _StateAbbr;
public string StateAbbr {
get { return_StateAbbr; }
set { _StateAbbr = value; }
}
private string _StateName;
public string StateName {
get { return _StateName; }
set { _StateName= value; }
}
0
All Courses

From novice to tech pro — start learning today.