通过反射获取System.Data.Odbc v8.0.0的DbProviderFactory遇空值问题
问题分析与解决
错误根源
System.Data.Odbc.OdbcFactory的Instance是静态公共属性,而非字段。你原代码中用BindingFlags.GetField去获取,与成员类型不匹配,因此返回null。其他数据提供商(如SqlClient)的Instance是静态字段,所以你的原代码能正常运行,但ODBC的实现逻辑不同。
修正后的代码
调整InvokeMember的BindingFlags参数,改用GetProperty来获取静态属性:
var odbcPath = @"..\lib\System.Data.Odbc.dll"; var asm = Assembly.LoadFrom(odbcPath); // 直接从加载的程序集中获取OdbcFactory类型,无需转AssemblyQualifiedName var factoryType = asm.DefinedTypes.FirstOrDefault(t => t.FullName.Equals("System.Data.Odbc.OdbcFactory", StringComparison.OrdinalIgnoreCase))?.AsType(); if (factoryType == null) { throw new InvalidOperationException("未找到OdbcFactory类型"); } // 获取静态公共属性Instance var _DbProviderFactory = factoryType.InvokeMember("Instance", BindingFlags.Public | BindingFlags.Static | BindingFlags.GetProperty, null, null, null) as DbProviderFactory; var con = _DbProviderFactory?.CreateConnection();
更简洁的实现方式
可以直接使用Type.GetProperty方法,代码可读性更强:
var odbcPath = @"..\lib\System.Data.Odbc.dll"; var asm = Assembly.LoadFrom(odbcPath); var factoryType = asm.GetType("System.Data.Odbc.OdbcFactory"); var instanceProperty = factoryType.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static); var _DbProviderFactory = instanceProperty.GetValue(null) as DbProviderFactory; var con = _DbProviderFactory.CreateConnection();
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

