Как насчет этого:
public IQueryable<IPerson> getPersons() {
// gives Types in Union or Concat have different members assigned error
var people = from p in db.Persons select p;
return (from s in people
where s.TypeId == (int)PersonType.Student
select new Student
{
Id = s.Id,
Age = s.Age.GetValueOrDefault(0),
Name = s.Name,
Major = s.Student.Major ?? "None",
CreditHours = s.Student.CreditHours.GetValueOrDefault(0),
PersonType = (PersonType)s.TypeId
}).Cast<IPerson>().Union((from e in people
where e.TypeId == (int)PersonType.Employee
select new Employee
{
Id = e.Id,
Age = e.Age.GetValueOrDefault(0),
Name = e.Name,
PersonType = (PersonType)e.TypeId,
Salary = e.Employee.Salary.GetValueOrDefault(0)
}).Cast<IPerson>());
}
Не намного лучше, но вы получаете это за один звонок. Или, что я бы сделал, это что-то вроде этого:
public IPerson GetPerson(Person p) //I'm guessing that the objects in collection db.Persons is of type Person
{
IPerson ret;
switch(p.TypeId)
{
case (int)PersonType.Student: ret = .......break;
case (int)PersonType.Employee: ret = ......break;
}
return ret;
}
public IQueryable<IPerson> getPersons() {
return (from p in db.Persons select p).ToList().Select(p => GetPerson(p)).AsQueryable();
}
Но, опять же, вы получаете заявление о переключении. Кроме того, если вам не нравится делать ToList () на БД (если я правильно помню, LinqToSQL не поддерживает функции, использующие конструкторы с переменными), вы можете попробовать добавить метод GetPerson (хотя я, вероятно, переименую его) в класс Person, сгенерированный LinqToSQL (частичный класс), но я не уверен, что это допустимо.
Но как вы собираетесь использовать IQueryable, полученный от getPersons, без использования switch, я не знаю.