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

C#从SQL外键表查询PC数据遇类型转换错误及品牌型号获取问题

PC数据查询异常修正方案

问题背景

搭建首个学习应用时,需要从PC表及关联的外键表(存储ID与对应名称)中获取数据,目标是显示PC的品牌、型号等名称而非ID。目前已能获取PC表基础数据,但出现System.InvalidCastException: 'Specified cast is not valid.'错误,且无法正确显示外键表的名称信息。

数据库表结构说明:

  • PC表包含PC_ID、PC_SERIAL、PC_NAME、PC_BRAND_ID、PC_MODEL_ID等外键ID字段
  • 关联表包括PC_BRAND(PC_BRAND_ID、PC_BRAND)、PC_MODEL(PC_MODEL_ID、PC_MODEL)、PC_NET(PC_NET_ID、PC_NET)、PC_OS(PC_OS_ID、PC_OS)、PC_RAM(PC_RAM_ID、PC_RAM),每个关联表均为ID+名称的结构

错误原因

  1. SQL查询列与转换逻辑不匹配:SQL仅返回了名称字段,但转换代码试图将这些字符串类型的名称列强制转换为int类型的外键ID,同时列索引越界(SQL返回7列,转换代码取到第8个索引)
  2. 模型定义错误:PC类中PC_Model的类型错误定义为PCBrand,而非对应的PCModel类
  3. 导航属性未实例化:转换代码仅赋值了外键ID,未实例化PC_Brand、PC_Model等导航属性,导致ToString无法显示名称

修正步骤

1. 修正SQL查询语句

需要同时返回外键ID和对应的名称字段,确保后续能正确映射导航属性:

private const string SqlGetAllPC = @"Select PC.PC_ID, PC.PC_NAME, PC.PC_SERIAL,
        PC.PC_BRAND_ID, PC_BRAND.PC_BRAND,
        PC.PC_MODEL_ID, PC_MODEL.PC_MODEL,
        PC.PC_NET_ID, PC_NET.PC_NET,
        PC.PC_OS_ID, PC_OS.PC_OS,
        PC.PC_RAM_ID, PC_RAM.PC_RAM
        FROM PC
        INNER JOIN PC_BRAND on PC.PC_BRAND_ID=PC_BRAND.PC_BRAND_ID
        INNER JOIN PC_MODEL ON PC.PC_MODEL_ID=PC_MODEL.PC_MODEL_ID
        INNER JOIN PC_NET ON PC.PC_NET_ID=PC_NET.PC_NET_ID
        INNER JOIN PC_OS ON PC.PC_OS_ID=PC_OS.PC_OS_ID
        INNER JOIN PC_RAM ON PC.PC_RAM_ID=PC_RAM.PC_RAM_ID";

2. 修正PC模型定义

将PC_Model的类型改为正确的PCModel:

public class PC
{
    public int PC_ID { get; set; }
    public string PC_SERIAL { get; set; }
    public string PC_NAME { get; set; }
    public Nullable<int> PC_BRAND_ID { get; set; }
    public PCBrand PC_Brand { get; set; }
    public Nullable<int> PC_MODEL_ID { get; set; }
    public PCModel PC_Model { get; set; } // 修正类型为PCModel
    public Nullable<int> PC_OS_ID { get; set; }
    public PCOS PC_OS { get; set; }
    public Nullable<int> PC_NET_ID { get; set; }
    public PCNet PC_Net { get; set; }
    public Nullable<int> PC_RAM_ID { get; set; }
    public PCRam PC_Ram { get; set; }

    public override string ToString()
    {
        return $"{PC_ID} - {PC_NAME} - {PC_SERIAL} - {PC_Model} - {PC_Brand} - {PC_OS} - {PC_Net} - {PC_Ram}";
    }
}

3. 给外键类添加ToString方法

确保PC的ToString能正确显示名称而非类名:

namespace Inventory.Data.Model
{
    public class PCBrand
    {
        public int PC_BRAND_ID { get; set; }
        public string PC_BRAND { get; set; }

        public override string ToString()
        {
            return PC_BRAND;
        }
    }

    public class PCModel
    {
        public int PC_MODEL_ID { get; set; }
        public string PC_MODEL { get; set; }

        public override string ToString()
        {
            return PC_MODEL;
        }
    }

    public class PCNet
    {
        public int PC_NET_ID { get; set; }
        public string PC_NET { get; set; }

        public override string ToString()
        {
            return PC_NET;
        }
    }

    public class PCOS
    {
        public int PC_OS_ID { get; set; }
        public string PC_OS { get; set; }

        public override string ToString()
        {
            return PC_OS;
        }
    }

    public class PCRam
    {
        public int PC_RAM_ID { get; set; }
        public string PC_RAM { get; set; }

        public override string ToString()
        {
            return PC_RAM;
        }
    }
}

4. 修正数据转换方法

在ConvertToPC中实例化导航属性,并正确映射SQL返回的列:

private IEnumerable<PC> ConvertToPC(DataTable data)
{
    List<PC> tmp = new List<PC>();

    foreach (DataRow row in data.Rows)
    {
        tmp.Add(new PC()
        {
            PC_ID = row.Field<int>(0),
            PC_NAME = row.Field<string>(1),
            PC_SERIAL = row.Field<string>(2),
            PC_BRAND_ID = row.Field<int?>(3),
            PC_Brand = new PCBrand()
            {
                PC_BRAND_ID = row.Field<int>(3),
                PC_BRAND = row.Field<string>(4)
            },
            PC_MODEL_ID = row.Field<int?>(5),
            PC_Model = new PCModel()
            {
                PC_MODEL_ID = row.Field<int>(5),
                PC_MODEL = row.Field<string>(6)
            },
            PC_NET_ID = row.Field<int?>(7),
            PC_Net = new PCNet()
            {
                PC_NET_ID = row.Field<int>(7),
                PC_NET = row.Field<string>(8)
            },
            PC_OS_ID = row.Field<int?>(9),
            PC_OS = new PCOS()
            {
                PC_OS_ID = row.Field<int>(9),
                PC_OS = row.Field<string>(10)
            },
            PC_RAM_ID = row.Field<int?>(11),
            PC_Ram = new PCRam()
            {
                PC_RAM_ID = row.Field<int>(11),
                PC_RAM = row.Field<string>(12)
            }
        });
    }

    return tmp;
}

验证

修改完成后,点击按钮执行查询,即可在弹窗中看到包含品牌、型号等名称的PC信息,同时System.InvalidCastException错误会被解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 20:40:55