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?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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
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
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

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
BeartlaoiCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.