Convert List<A> to List<B> with Linq c#

Viewed 2950

How can i convert my list with typ "Person" (created by my database) to typ "myPerson" without getting erros.

I tried this :

DataClasses1DataContext d = new 
DataClasses1DataContext(MainWindow.mySqlClass.GetConnection());

var query = from pers in d.Person select pers;

personen = query.ToList();
newPerson = personen.Cast<myPerson>().ToList();

But I only get a System.InvalidCastException.

public partial class myPerson : Person
{
    public override string ToString()
    {
        return Name + " " + Nachname;
    }
    public myPerson(System.Data.Linq.EntitySet<Bilder> bilder, string geschlecht, int iD, string nachname, string name)
    {
        Bilder = bilder;
        Geschlecht = geschlecht;
        ID = iD;
        Nachname = nachname;
        Name = name;
    }
}

The Class that Linq created (just the frist rows):

public partial class Person : INotifyPropertyChanging, INotifyPropertyChanged
{

    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

    private int _ID;

    private string _Nachname;

    private string _Name;

    private string _Geschlecht;

    private EntitySet<Bilder> _Bilder;

anyone has a idea how can i convert a List from typ Person to a List with typ myPerson?

or how can i make a "query" that gives can convert from Person to myPerson?

4 Answers

Every myPerson instance can be casted to Person because the myPerson class inherits from Person. But you can't do the opposite, cast a Person to myPerson so the parent to the child. You could do that only if it was really a myPerson, but it is not in this case so the cast fails.

If you have a Person and you want to convert it to myPerson you should provide a constructor (or factory method) that accepts a Person instance and initializes (or returns) the myPerson instance.

public partial class myPerson : Person
{
    public myPerson(Person p)
    {
        _ID = p.Id;
        _Nachname = p.Nachname;
        _Name = p.Name;
        _Geschlecht = p.Geschlecht;
        _Bilder = p.Bilder;
    }

    private int _ID;
    private string _Nachname;
    private string _Name;
    private string _Geschlecht;
    private EntitySet<Bilder> _Bilder;
    // add properties
}

Then you can use:

personen = query.ToList();
newPerson = personen.Select(p => new myPerson(p)).ToList();
var query = from pers in d.Person 
            select new myPerson 
                  {
                     Name = pers.Name,
                     ...
                  } ;

Replace the dots (...) with the rest of the properties you want to map.

Irrespective of entity framework or not, you cannot cast from a collection of classes into a collection of subclasses.

You need to make a new collection, in this case a new List, and fill it with new objects that you make. You could do that with a select in linq like this:

d.Person.Select(x => new myPerson(....)).ToList();

Which would go through all the Person instances, create a new myPerson for each one, and convert the result to a List.

Don't write the .... though - you need to do this according to your definition of the ctor of myPerson, copying all the fields of Person into myPerson eg:

new myPerson(x.Bilder, x.Geschlecht, .......

Or as commented, make a ctor for myPerson that takes a Person, then inside the ctor you can copy the fields you need.

Perhaps this StackOverflow solves your problem ?

Here is the accepted answer from Botz3000: "

ChildClassList = BaseClassList.Cast<ChildClass>().ToList();

Your current code adds null if a BaseClass item cannot be cast to ChildClass. If that was really your intention, this would be equivalent:

ChildClassList = BaseClassList.Select(x => x as ChildClass).ToList();

But i'd rather suggest this, which includes type checking and will skip items that don't match:

ChildClassList = BaseClassList.OfType<ChildClass>().ToList();

"

Related