.NET Core/EF Core 2.0升级后,Eager Loading出现“类型之间未定义强制转换运算符”的问题

3
在.NET Core 1.x中,我们有一个看起来像这样的方法:
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);
}

这对我们非常有用。在将整个项目升级到.NET Core 2.0和EF Core 2.0后,该方法抛出以下异常:

System.InvalidOperationException发生:在类型“PaperPointerRecord”和“PaperRecord”之间未定义强制转换运算符。

此异常发生在以下代码块中:

var record = await query.Include(_ => _.Paper)
                        .ThenInclude(_ => _.PaperColors)
                        .Select(_ => new
                                     {
                                         PaperRecord = _.Paper,
                                         PaperPointerRecord = _
                                     })
                        .SingleOrDefaultAsync();

如果我移除了急加载并将其改为以下方式,那么错误就消失了,但是我也无法获得预期的结果:
var record = await query.Select(_ => new
                                     {
                                         PaperRecord = _.Paper,
                                         PaperPointerRecord = _
                                     })
                        .SingleOrDefaultAsync();

我查看了Microsoft文档,没有显示我们在使用贪婪加载方面存在错误。
1个回答

2

Include在这种情况下没有用处,因为您正在返回一个投影,并且Include会被忽略(了解有关忽略包含的信息在此)。

如果您所说的“预期结果”是希望record.PaperRecord.Paper具有值,则只需在投影中包含它; EF将连接关系。

new
{
    PaperRecord = _.Paper,
    PaperPointerRecord = _,
    PaperColor = _.Paper.PaperColor,
}

我完全同意你的评估。我基本上按照你的建议解决了这个问题。最终代码变得更简洁明了。但是让我担心的是,它在1.x中运行良好,在2.0中却出现了问题。在某些方面,这有助于使事情变得更好。但情况有点被迫,需要我们重新编写很多代码。 - Ristogod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接