I know there's a way to do this but I've been banging my head against a wall trying to figure it out. This works fine:
private GenericRecord CreateGeneric(GenericRecord g, Member m)
{
g.Member = m;
return g;
}
public IList<GenericRecord> ReportFromDatabase(DateTime startDate, DateTime endDate)
{
List<GenericRecord> returnRecords = new List<GenericRecord>();
returnRecords.AddRange(from r in pjRepository.Records
join m in memberRepository.Members on r.SID equals m.MemberId.ToString()
where r.TransactionDate >= startDate && r.TransactionDate <= endDate
select CreateGeneric((GenericRecord)r, m));
return returnRecords;
}
But I know there's a way to do it without the CreateGeneric function. How do I select a delegate function inline?
returnRecords.AddRange(from r in pjRepository.Records
join m in memberRepository.Members on r.SID equals m.MemberId.ToString()
where r.TransactionDate >= startDate && r.TransactionDate <= endDate
select (delegate
{
GenericRecord g = (GenericRecord)r;
g.Member = m;
return g;
}));
That gives me this exception:
The type of the expression in the select clause is incorrect. Type inference failed in the call to 'Select'.
Edit: Another failed attempt
returnRecords.AddRange((from r in pjRepository.Records
join m in memberRepository.Members on r.SID equals m.MemberId.ToString()
where r.TransactionDate >= startDate && r.TransactionDate <= endDate
select new { r, m }).Select(x =>
{
GenericRecord g = (GenericRecord)x.r;
g.Member = x.m;
return g;
}));
This gives me:
A lambda expression with a statement body cannot be converted to an expression tree.
Try:
returnRecords.AddRange((from r in pjRepository.Records
join m in memberRepository.Members on r.SID equals m.MemberId.ToString()
where r.TransactionDate >= startDate && r.TransactionDate <= endDate
select new { r, m }).AsEnumerable().Select(x =>
{
GenericRecord g = (GenericRecord)x.r;
g.Member = x.m;
return g;
}));
The key different is that AsEnumerable() function. That takes an IQueryable and returns an IEnumerable, which behind the scenes forces the evaluation of the expression tree by the Linq provider. This prevents the Linq library from attempting to convert the second Select's lambda to part of the expression tree (which it says it can't); the second Select will instead perform its transformation on the actual im-memory collection produced by evaluating the IQueryable expression tree. Since you require the query to be evaluated before the statement ends anyway (so all the elements can be added to returnRecords), there should be no significant performance difference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With