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

SQL数据表加载到DataView时出现System.InvalidCastException错误排查

问题描述

我用以下SQL语句创建了数据表:

CREATE TABLE AAPL_1day
(
    [INDEX] INT IDENTITY(1,1) PRIMARY KEY,
    [DateTime] SMALLDATETIME NOT NULL,
    [MonthNr] FLOAT NOT NULL,
    [DayNr] FLOAT NOT NULL,
    [roc_1] FLOAT,
    [roc_2] FLOAT,
    [hypo_upordown7days] FLOAT
);

尝试用ML.NET将表数据加载到data变量时,调用data.Preview()抛出错误:

System.InvalidCastException: 'Specified cast is not valid.'

数据库连接验证正常,表中目标列均为FLOAT类型,对应C#实体类的属性也定义为float,但即使仅读取单个列,错误依然触发。相关C#代码如下:

void loadInData()
{
    // Set up MLContext
    var mlContext = new MLContext();

    // Define database connection parameters
    string databaseName = "AAPL";
    string connectionString = "Server=localhost;Database=" + databaseName + ";Trusted_Connection=True;";
    var tableName = "AAPL_1day";

    var loader = mlContext.Data.CreateDatabaseLoader<AAPLData>();
    var source = new DatabaseSource(SqlClientFactory.Instance, connectionString, $"SELECT * FROM {tableName}");
    var data = loader.Load(source);
    var preview = data.Preview(); // 触发System.InvalidCastException

    string dummy_breakpoint = ""; // 断点位置
}

public class AAPLData
{
    [LoadColumn(2)] public float MonthNr;
    [LoadColumn(3)] public float DayNr;
    [LoadColumn(4)] public float roc_1;
    [LoadColumn(5)] public float roc_2;
    [LoadColumn(6), ColumnName("Label")] public float hypo_upordown7days;
}
解决方案

1. 修正类型匹配问题

SQL Server中的FLOAT默认是双精度浮点型(FLOAT(53)),对应C#的double而非float(单精度)。将实体类中的所有float改为double即可解决类型转换错误:

public class AAPLData
{
    [LoadColumn(2)] public double MonthNr;
    [LoadColumn(3)] public double DayNr;
    [LoadColumn(4)] public double roc_1;
    [LoadColumn(5)] public double roc_2;
    [LoadColumn(6), ColumnName("Label")] public double hypo_upordown7days;
}

2. 优化查询语句(可选)

避免使用SELECT *,明确指定需要加载的列,减少不必要的数据读取,同时确保列顺序与LoadColumn索引对应:

var source = new DatabaseSource(SqlClientFactory.Instance, connectionString, 
    $"SELECT MonthNr, DayNr, roc_1, roc_2, hypo_upordown7days FROM {tableName}");

此时需将LoadColumn的索引调整为从0开始:

public class AAPLData
{
    [LoadColumn(0)] public double MonthNr;
    [LoadColumn(1)] public double DayNr;
    [LoadColumn(2)] public double roc_1;
    [LoadColumn(3)] public double roc_2;
    [LoadColumn(4), ColumnName("Label")] public double hypo_upordown7days;
}

3. 使用列名映射替代索引(更可靠)

通过ColumnName属性直接绑定数据库列名,无需依赖列顺序,避免索引错误:

public class AAPLData
{
    [ColumnName("MonthNr")] public double MonthNr;
    [ColumnName("DayNr")] public double DayNr;
    [ColumnName("roc_1")] public double roc_1;
    [ColumnName("roc_2")] public double roc_2;
    [ColumnName("hypo_upordown7days"), ColumnName("Label")] public double hypo_upordown7days;
}

此时查询语句保持SELECT MonthNr, DayNr, roc_1, roc_2, hypo_upordown7days FROM {tableName}即可,无需指定LoadColumn索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 11:34:51