.NET Core 3.1 WinForms设计器加载继承BaseForm窗体时EF Core DisposeAsync报错
问题原因分析
- 首先,
DesignerSerializationVisibility.Hidden特性的作用仅为控制设计器序列化时不生成该属性的相关代码,完全不阻止设计器反射扫描窗体类的所有公共属性的类型元数据。设计器加载继承窗体时,会主动扫描BaseForm的所有公共属性,触发对DataContext类型的元数据加载,进而需要加载EF Core相关程序集的元信息。 - 其次,.NET Core 3.1 版本的 WinForms 设计器运行在 Visual Studio 的 .NET Framework 宿主进程中,和你的项目运行环境不一致。EF Core 3.1.19 的
DbContext对IAsyncDisposable接口的DisposeAsync方法实现是面向 .NET Core 环境的,在 .NET Framework 环境的设计器进程中加载程序集元数据时,无法匹配到对应的实现,就会抛出「方法没有实现」的异常,这个异常和你自己在子类实现的DisposeAsync方法无关。
解决方案
- 方案1:修改属性的访问级别,将
public DataContext con { get; set; }改为internal DataContext con { get; set; }。设计器默认只会处理公共属性,internal 级别的属性不会被设计器扫描,自然不会触发EF Core相关的类型加载逻辑。 - 方案2:如果需要保留public访问级别,为属性追加两个特性,明确告知设计器忽略该属性:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] public DataContext con { get; set; }
[Browsable(false)] 会让属性不显示在设计器的属性窗口中,[EditorBrowsable] 会告诉设计器不要反射读取该属性的元数据。
- 方案3:在
BaseForm的构造函数中增加设计模式判断,设计模式下不初始化任何和EF Core相关的实例,避免设计器加载相关类型:
public BaseForm() { if (!DesignMode) { // 仅运行时执行的初始化逻辑,包括DataContext的初始化 } }
内容的提问来源于stack exchange,提问作者Florent
相关产品推荐
相关产品推荐

