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

EF Core 7执行SqlQuery查询自定义类型报错,EF 6可正常运行求助

在EF Core 7中解决自定义类型SqlQuery报错的方案

问题场景

执行以下SQL查询时触发错误:

SELECT * FROM TABLE(MY_CUSTOM_FU(:my_param))

报错信息:

System.InvalidOperationException: 'The element type 'MyCustomRow' used in 'SqlQuery' method is not natively supported by your database provider. Either use a supported element type, or use ModelConfigurationBuilder.DefaultTypeMapping to define a mapping for your type.'

该查询在EF 6中通过SqlQueryRaw可以正常执行:

rows = Database.SqlQueryRaw<MyCustomRow>("SELECT * FROM TABLE(MY_CUSTOM_FU(:my_param))", myParam);

解决方法

1. 配置自定义类型的默认映射

在你的DbContext的OnModelCreating方法中,使用ModelConfigurationBuilder为MyCustomRow定义类型转换逻辑,适配数据库提供商的要求:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.DefaultTypeMapping<MyCustomRow>()
        .HasConversion(
            // 将MyCustomRow转换为数据库支持的类型(示例逻辑,需根据实际数据库调整)
            row => 
            {
                // 比如Oracle环境下构建OracleDataRecord,SqlServer下可对应SqlDataRecord
                // 需匹配存储过程返回的列结构
            },
            // 从数据库返回值转换回MyCustomRow
            dbValue => 
            {
                var customRow = new MyCustomRow();
                // 根据数据库返回的字段赋值给customRow的属性
                customRow.Id = dbValue.GetInt32(0);
                customRow.Name = dbValue.GetString(1);
                return customRow;
            });
}

2. 手动读取DataReader并转换

绕过EF Core的类型映射,直接使用DataReader读取结果后手动映射到MyCustomRow:

using var reader = await Database.ExecuteSqlRawAsync("SELECT * FROM TABLE(MY_CUSTOM_FU(:my_param))", myParam);
var rows = new List<MyCustomRow>();

while (reader.Read())
{
    var row = new MyCustomRow
    {
        // 根据查询结果的列顺序或名称赋值
        PropertyA = reader.GetInt32(reader.GetOrdinal("PropertyA")),
        PropertyB = reader.GetString(reader.GetOrdinal("PropertyB"))
        // 其他属性依次配置
    };
    rows.Add(row);
}

await reader.CloseAsync();

3. 将MyCustomRow注册为无键实体

如果MyCustomRow的结构适合作为EF Core实体(无需对应物理表),可以将其注册为无键实体,让EF Core识别该类型:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // 注册为无键实体,因为自定义返回类型通常没有主键
    modelBuilder.Entity<MyCustomRow>().HasNoKey();
}

之后即可正常使用SqlQuery:

rows = await Database.SqlQuery<MyCustomRow>("SELECT * FROM TABLE(MY_CUSTOM_FU(:my_param))", myParam).ToListAsync();

内容的提问来源于stack exchange,提问作者Djamel Besseghir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 23:10:06