Hi All, Yes, this is my fourth day in a row to ask a question about abstracts, sorry, I'll try and go answer some questions about SQLServer to return the favor to the community. Anyway...
How can I project the results of a Linq query into a abstract base class collection? Here is my my method from my RecruiterBase abstract class (there is also a corresponding CandidateBase abstract class):
public IQueryable<CandidateBase> GetCandidates()
{
return from candidates in db.Candidates
where candidates.RecruiterId == this.RecruiterId
select candidates;
}
The above method will throw a compile time error that an implicit conversion cannot be made between Candidate and CandidateBase.
modifying db.Candidates to db.Candidates.Cast() lets everything compile but I get a runtime error that no coercion operator is defined between types Candidate and CandidateBase.
I can't do: select New CandidateBase { ... } as CandidateBase since the abstract can't be implemented.
Nor can I create an explicit conversion operator between Candidate and Candidate base because it would again require me to new up my abstract
Nor can I project my results into an anonymous object and then cast to CandidateBase as I get the same runtime coercion exception between the anonymous type and CandidateBase type.
This problem came about from yesterday's question, http://stackoverflow.com/questions/1337327/problem-with-covariant-return-types-from-an-abstract-method
The answer provided by Stan R was that I was making things to complicated. I went back, simplified everything (I left the implmentation in the base and removed it from the subs) and ended up with a working GetCanidates method implemented as such:
public IQueryable<CandidateBase> GetCandidates()
{
return (from candidates in db.Candidates
where candidates.RecruiterId == this.RecruiterId
select new CandidateA
{
CandidateId = candidates.CandidateId,
LastName = candidates.LastName,
RecruiterId = candidates.RecruiterId
}).Cast<CandidateBase>();
}
The above method compiles and works, and I'm not trying to look a gift horse in the mouth, but now I have a reference to my subtype in my base type (when I project the results into CandidateA) and that just seems odd. Feel free to vote my question down if the reference to the subtype from within the base type is okay.
Thanks.
Full class defs:
public abstract class RecruiterBase
{
public int RecruiterId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public RecruiterBase()
{
}
public RecruiterBase(int id)
{
DataClasses1DataContext db = new DataClasses1DataContext();
Recruiter rc = db.Recruiters.SingleOrDefault(r => r.RecruiterId == id);
this.RecruiterId = rc.RecruiterId;
this.FirstName = rc.FirstName;
this.LastName = rc.LastName;
}
public IQueryable<CandidateBase> GetCandidates()
{
DataClasses1DataContext db = new DataClasses1DataContext();
return (from candidates in db.Candidates
where candidates.RecruiterId == this.RecruiterId
select new CandidateA
{
CandidateId = candidates.CandidateId,
LastName = candidates.LastName,
FirstName = candidates.FirstName,
RecruiterId = candidates.RecruiterId
}
).Cast<CandidateBase>();
}
}
public abstract class TempCandidateBase
{
public int CandidateId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int? RecruiterId { get; set; }
public CandidateBase()
{
}
public CandidateBase(int id)
{
DataClasses1DataContext db = new DataClasses1DataContext();
Candidate candidate = db.Candidates.SingleOrDefault(c => c.CandidateId == id);
this.CandidateId = candidate.CandidateId;
this.FirstName = candidate.FirstName;
this.LastName = candidate.LastName;
this.RecruiterId = candidate.RecruiterId;
}
}
public class RecruiterA : RecruiterBase
{
public RecruiterA()
: base()
{
}
public RecruiterA(int id)
: base(id)
{
}
}
public class CandidateA : CandidateBase
{
public CandidateA()
: base()
{
}
public CandidateA(int id)
: base(id)
{
}
}