In .NET Core 1.x, we had a method that looked like this:
public async Task<(PaperRecord Component, PaperPointerRecord Pointer)> GetOneAsync(DbSet<PaperPointerRecord> paperPointerRecords,
int? paperId = null,
long? externalPaperId = null,
Expression<Func<PaperPointerRecord, bool>> filter = null)
{
var query = filter is null ? paperPointerRecords.AsQueryable() : paperPointerRecords.Where(filter);
if (paperId.HasValue)
query = query.Where(_ => _.PaperPointerId == paperId);
if (externalPaperId.HasValue)
query = query.Where(_ => _.ExternalId == externalPaperId);
var record = await query.Include(_ => _.Paper)
.ThenInclude(_ => _.PaperColors)
.Select(_ => new
{
PaperRecord = _.Paper,
PaperPointerRecord = _
})
.SingleOrDefaultAsync();
return !(record is null) ? (record.PaperRecord, record.PaperPointerRecord) : throw NewPaperRecordNotFoundException(paperId, externalPaperId);
}
This worked great for us. After upgrading the entire project to everything .NET Core 2.0 & EF Core 2.0, the method throws this exception:
System.InvalidOperationException occurred: No coercion operator is defined between types 'PaperPointerRecord' and 'PaperRecord'.
This exception is occuring in this block:
var record = await query.Include(_ => _.Paper)
.ThenInclude(_ => _.PaperColors)
.Select(_ => new
{
PaperRecord = _.Paper,
PaperPointerRecord = _
})
.SingleOrDefaultAsync();
If I remove the eager loading and make it like so, then the error goes away, but I don't get the intended results either:
var record = await query.Select(_ => new
{
PaperRecord = _.Paper,
PaperPointerRecord = _
})
.SingleOrDefaultAsync();
I've checked the Microsoft Documentation for this and I don't see anything being shown there that indicates we are doing something wrong with eager loading.
Include
isn't useful in this situation as you are returning a projection and the Include
s are ignored (read about ignored includes here).
If by "intended results" you mean you want record.PaperRecord.Paper
to have a value, simply include it in your projection; EF will wire up the relationship.
new
{
PaperRecord = _.Paper,
PaperPointerRecord = _,
PaperColor = _.Paper.PaperColor,
}