Binding IQueryable Derived class to ListView Raises Exception
Linq to SQL supports single table inheritance. So if you have an employee table, you can store both Salaried and Hourly Employee in a single table. To identify which employee is what, you can use discriminator column. To map a table that contains multiple derived classes in Linq to SQL, you have to do 3 things. For each derived class, you have to specify what discriminator column to use. Secondly you have specify what value in the discriminator column identifies a particular derived class. Third you have to specify what should be the default derived class in the case where database does not define a value for the discriminator column. In the example below I have an employee class which has two derived classes, SalariedEmployee and HourlyEmployee.
In the above screen shot, for the case of Hourly Employee, I am telling to use Type as the discriminator column and the discriminator value of HE to be associated with Hourly Employee as the derived class. I am also stating to use Hourly Employee to be the default derived class in case of missing value for Type column in the database. The parameters for Salaried Employee are exactly the same except the discriminator value of SE would be mapped to Salaried Employee derived class.
Since each employee has a different way of getting salary like Salaried Employee has a fixed salary where as Hourly Employee gets their salary by multiplying the hourly rate by number of hours worked, I create an abstract method on Employee class which both employees are required to override. Below code shows the concrete implementation of each derived classes.
In the above code, both Hourly and Salaried employee, specify their own implementation of how to calculate TotalSalary for an employee. I have created another method called GetHourlyEmployee which simply returns all hourly employees in our database. To get Hourly Employees, I make use OfType operator specifying Hourly Employee as the generic type. OfType operator returns an IQueryable of Hourly Employees.
The next step is bind the results returned by GetHourlyEmployees method to a ListView control. Screen shot below shows an example of binding derived class Hourly Employee to a ListView control.
In the above code, I am binding HourlyEmployee collection to a ListView control and displaying FirstName and TotalSalary as shown by the ItemTemplate. When I run the page, I get the following exception.
I am not sure why I am getting this exception. In the past, I have been able to bind IQueryable to ListView control without problems. The only difference with this example is, I am binding IQueryable that consists of derived class such as an HourlyEmployee. One way that I have managed to solve the problem is by first converting my IQueryable results returned from GetHourlyEmployees method to ToList, forcing the results to be brought in memory and than binding the ListView to the results returned from ToList.
I am curious to know why directly binding IQueryable derived class does not work with ListView. If any of the readers know the answer, please feel free to put your comments.