You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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));

修复代码中的其他编译错误

你的动态代码还存在几个语法/逻辑问题,一并修正才能正常编译:

  1. ExecuteQuery方法不能直接定义在类外部,必须放到Program类内部
  2. _connectionString未定义,需添加类级字段或方法参数
  3. CommandType未指定命名空间,需添加using System.Data;或使用完整限定名
  4. 字符串替换中的引号转义逻辑错误

修正后的完整代码如下:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 02:36:18