Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I cast to subclass when using LINQ and TPT EF?

I have the following class hierarchy:

public class RealPeople { }

public class Users : RealPeople { }
public class People : RealPeople { }

In my dbContext, I defined a dbSet for RealPeople and on the OnModelCreating procedure, I specified separated tables for People and Users:

modelBuilder.Entity<Users>().ToTable("Users");
modelBuilder.Entity<People>().ToTable("People");

This creates the corresponding full hierarchy in my DB, with the 3 corresponding tables. The problem comes when I want to retrieve the list of Users in my DB. This:

List = (from Reg in PersistentMgr.RealPeople select (Users)Reg)
       .ToList();

or this:

List = (from Reg in PersistentMgr.RealPeople select (Users)((RealPeople)Reg))
       .ToList();

Throws an exception:

LINQ only being able to cast primitive model types.

So the thing is, I can't cast RealPeople to the corresponding subclass Users. Any ideas on this one?

like image 654
Alvaro Avatar asked Oct 08 '12 23:10

Alvaro


2 Answers

The way to get a collection of subclasses is using OfType:

var users = (from p in PersistentMgr.RealPeople select p).OfType<User>();
like image 143
Gert Arnold Avatar answered Nov 04 '22 18:11

Gert Arnold


Try this instead:

var list = PersistentMgr.RealPeople.Select(reg => reg as Users).ToList();

better:

var list = PersistentMgr.RealPeople.Select(reg => (reg is Users) ? reg as Users : null).ToList();

You will get the same error if you try this:

var realperson = new RealPeople();
var user = (Users) realperson;

The reason is because the compiler doesn't know how to convert complex types into their subtypes by simple casting - so you need to use the as keyword instead. This will either return null, or the supertype casted into the subtype.

var realperson = new RealPeople();
var user = realperson as Users; // user is realperson converted into a Users object
var aString = "this is a string";
var otheruser = aString as Users; // otheruser is null, because aString was not a valid supertype for Users
like image 36
rikkit Avatar answered Nov 04 '22 18:11

rikkit