在子类 objects 上使用 ToListAsync 的随机 InvalidCastException
Random InvalidCastException using ToListAsync on subclass objects
上下文
- 我正在使用 Entity Framework Core、SQLite 及其 spellfix1 扩展。
- 有两个类:
MetaMovie
和FuzzyMetaMovie
FuzzyMetaMovie
是 MetaMovie
的子类
描述
首先,我使用 db.MetaMovies.Where(...)
得到一个 IQueryable<MetaMovie> correspondingMovies
。如果没有结果,那么我使用 db.FuzzyMetaMovies.FromRawSql(...)
分配给类型相同的 IQueryable<MetaMovie>
变量。最后,我调用 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'
.
然后,我尝试调用其中一个特别失败的代码。没有任何问题!!单独尝试失败的任何一个都不会造成问题。所以,我的意思是这里它完全通过相同的代码路径并且没有抛出异常。
我真的不知道为什么会这样。我知道,你这里没有工作代码。但是,我无法规避这个问题,因此没有简单的方法来重现它。
有什么想法吗?
编辑 #1
我写了一个补丁解决方案来解决这个问题(请参阅下面我的解决方案)。不过,我将解释如何重现它:
上下文
- 有两个类,一个是另一个的child:
A
是B
的parent。
- 类 与鉴别器列共享相同的 table。
AsNoTracking()
未使用
步骤
- 创建一个查询,加载一个 object A with Id == 1
- 进行另一个查询,加载 Id ==1
的 object B
崩溃的根本原因
这是由于 EntityFramework 试图加载类型为 B
的实体,而该实体已被缓存为类型 A
。因此,从 A
到 B
.
的向下转换失败
问题出在之前的调用中,该调用至少加载了一部由原始查询获取的电影。
为了修复它,我使用了(所以没有使用缓存):
List<MetaMovie> tempList = await correspondingMovies.AsNoTracking().ToListAsync();
我在 GitHub 中为 efcore 项目开了一个问题:https://github.com/dotnet/efcore/issues/27802
上下文
- 我正在使用 Entity Framework Core、SQLite 及其 spellfix1 扩展。
- 有两个类:
MetaMovie
和FuzzyMetaMovie
FuzzyMetaMovie
是MetaMovie
的子类
描述
首先,我使用 db.MetaMovies.Where(...)
得到一个 IQueryable<MetaMovie> correspondingMovies
。如果没有结果,那么我使用 db.FuzzyMetaMovies.FromRawSql(...)
分配给类型相同的 IQueryable<MetaMovie>
变量。最后,我调用 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'
.
然后,我尝试调用其中一个特别失败的代码。没有任何问题!!单独尝试失败的任何一个都不会造成问题。所以,我的意思是这里它完全通过相同的代码路径并且没有抛出异常。
我真的不知道为什么会这样。我知道,你这里没有工作代码。但是,我无法规避这个问题,因此没有简单的方法来重现它。
有什么想法吗?
编辑 #1
我写了一个补丁解决方案来解决这个问题(请参阅下面我的解决方案)。不过,我将解释如何重现它:
上下文
- 有两个类,一个是另一个的child:
A
是B
的parent。 - 类 与鉴别器列共享相同的 table。
AsNoTracking()
未使用
步骤
- 创建一个查询,加载一个 object A with Id == 1
- 进行另一个查询,加载 Id ==1 的 object B
崩溃的根本原因
这是由于 EntityFramework 试图加载类型为 B
的实体,而该实体已被缓存为类型 A
。因此,从 A
到 B
.
问题出在之前的调用中,该调用至少加载了一部由原始查询获取的电影。
为了修复它,我使用了(所以没有使用缓存):
List<MetaMovie> tempList = await correspondingMovies.AsNoTracking().ToListAsync();
我在 GitHub 中为 efcore 项目开了一个问题:https://github.com/dotnet/efcore/issues/27802