在子类对象上使用ToListAsync的随机InvalidCastException



上下文

  • 我正在使用实体框架核心、SQLite及其spellfix1扩展
  • 有两个类:MetaMovieFuzzyMetaMovie
  • FuzzyMetaMovieMetaMovie的一个子类

描述

首先,我使用db.MetaMovies.Where(...)得到了一个IQueryable<MetaMovie> correspondingMovies。如果没有结果,那么我使用分配给IQueryable<MetaMovie>类型的同一变量的db.FuzzyMetaMovies.FromRawSql(...)。最后,我打电话给List<MetaMovie> tempList = await correspondingMovies.ToListAsync();

问题

问题来自最后一行。我有时会得到InvalidCastException: Unable to cast object of type 'Castle.Proxies.MetaMovieProxy' to type 'com.cyberinternauts.all.MediaRecognizer.Models.Metas.FuzzyMetaMovie'

I、 然后,尝试调用其中一个特别失败的代码。没问题!!任何一个单独尝试的失败都不会造成问题。所以,我的意思是,它完全通过相同的代码路径,并且不会抛出异常。

我真的不知道为什么会发生这种事。我知道,你这里没有工作代码。但是,我无法绕过这个问题,因此没有简单的方法来复制它

知道吗?

编辑#1

我写了一个补丁解决方案,可以做到这一点(见下面的解决方案(。不过,我将解释如何复制它:

上下文

  • 有两个类,一个是另一个的子类:AB的父类
  • 这些类共享具有鉴别器列的同一个表
  • 未使用AsNoTracking()

步骤

  • 进行一个查询,加载Id为1的对象a
  • 进行另一个查询以加载Id为1的对象B

崩溃的根本原因

这是由于EntityFramework试图加载已缓存为类型A的类型B的实体造成的。因此,从AB

问题来自以前的调用,该调用加载了至少一个由原始查询获取的电影。

为了修复它,我使用了(所以没有使用缓存(:

List<MetaMovie> tempList = await correspondingMovies.AsNoTracking().ToListAsync();

我在GitHub中为efcore项目打开了一个问题:https://github.com/dotnet/efcore/issues/27802

最新更新