ASP.NET Core项目用Roslyn编译时遇Component引用缺失问题
解决Roslyn动态编译时缺少System.ComponentModel.Primitives引用的问题
核心问题修复:添加缺失的程序集引用
错误提示的本质是动态编译时缺少System.ComponentModel.Primitives程序集引用——SqlConnection等类继承自Component,而Component类型正是定义在这个程序集中。
在你的引用列表中添加以下代码即可解决该错误:
// 方式1:通过类型加载更可靠,避免版本匹配问题 references.Add(MetadataReference.CreateFromFile(typeof(System.ComponentModel.Component).Assembly.Location)); // 或者方式2:通过程序集名称加载 references.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.ComponentModel.Primitives")).Location));
修复代码中的其他编译错误
你的动态代码还存在几个语法/逻辑问题,一并修正才能正常编译:
ExecuteQuery方法不能直接定义在类外部,必须放到Program类内部_connectionString未定义,需添加类级字段或方法参数CommandType未指定命名空间,需添加using System.Data;或使用完整限定名- 字符串替换中的引号转义逻辑错误
修正后的完整代码如下:
List<MetadataReference> references = new List<MetadataReference>(); references.Add(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)); references.Add(MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location)); references.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Console")).Location)); references.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Runtime")).Location)); references.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Data.SqlClient")).Location)); references.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Data")).Location)); references.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Data.Common")).Location)); references.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.ComponentModel.DataAnnotations")).Location)); // 添加缺失的System.ComponentModel.Primitives引用 references.Add(MetadataReference.CreateFromFile(typeof(System.ComponentModel.Component).Assembly.Location)); var code = @" using System; using System.Data; using System.Data.SqlClient; class Program { // 定义数据库连接字符串字段 private string _connectionString = ""你的数据库连接字符串""; static void Main(string[] args) { Console.WriteLine(1); } public DataTable ExecuteQuery(string query) { query = query.Replace("""""", ""''""); DataTable dataTable = new DataTable(); using (var con = new SqlConnection(_connectionString)) { using var sqlCommand = con.CreateCommand(); sqlCommand.CommandType = CommandType.Text; sqlCommand.CommandText = query; con.Open(); SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlCommand); sqlDataAdapter.Fill(dataTable); } return dataTable; } }"; SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code); string assemblyName = Path.GetRandomFileName(); CSharpCompilation compilation = CSharpCompilation.Create( assemblyName, syntaxTrees: new[] { syntaxTree }, references: references, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, usings: new[] { "System", "System.IO", "System.Linq", "System.Collections.Generic" }) ); using (var ms = new MemoryStream()) { EmitResult result = compilation.Emit(ms); if (result.Success) { ms.Seek(0, SeekOrigin.Begin); Assembly assembly = Assembly.Load(ms.ToArray()); Type type = assembly.GetType("Program"); // Main是静态方法,无需实例化即可调用 var mainOutput = type.InvokeMember("Main", BindingFlags.Default | BindingFlags.InvokeMethod | BindingFlags.Static, null, null, new object[] { new string[0] }); // 调用实例方法ExecuteQuery object obj = Activator.CreateInstance(type); var queryOutput = type.InvokeMember("ExecuteQuery", BindingFlags.Default | BindingFlags.InvokeMethod | BindingFlags.Instance, null, obj, new object[] { "SELECT * FROM YourTable" }); } else { // 编译失败时输出错误信息,方便排查 foreach (var diagnostic in result.Diagnostics) { Console.WriteLine(diagnostic.ToString()); } } }
额外说明
- 调用静态方法时,需添加
BindingFlags.Static标记,无需创建类实例 - 建议保留编译失败时的错误输出逻辑,快速定位问题
内容的提问来源于stack exchange,提问作者Green
相关产品推荐
相关产品推荐

