Eager Loading "No coercion operator is defined between types" after .NET Core/EF Core 2.0 Upgrade

.net-core c# eager-loading entity-framework-core linq

Question

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.

1
3
9/20/2017 1:34:43 PM

Accepted Answer

Include isn't useful in this situation as you are returning a projection and the Includes 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,
}
2
9/20/2017 2:47:36 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow