简体   繁体   English

如何使用 C# 从 SQL 的外键表中检索数据

[英]How can I retrieve data from a foreign key table in SQL with C#

I'm trying to build my first application for learning purposes but I've hit a wall.. My goal is to retrieve data from a table labeled PC and several foreign key tables that has an ID and a string value.我正在尝试构建我的第一个用于学习目的的应用程序,但我遇到了困难。我的目标是从一个标有 PC 的表和几个具有 ID 和字符串值的外键表中检索数据。 I was able to do a SQL query that retrieved all the information from the PC table (uncluding foreign key ID's) but I want to be able to see the "brand" and "model" of a pc.我能够执行 SQL 查询,从 PC 表中检索所有信息(不包括外键 ID),但我希望能够看到电脑的“品牌”和“型号”。

My errormessage我的错误信息

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

My PC model in C# looks like this我的电脑 model 在 C# 看起来像这样

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 PCBrand PC_Model { get; set; }
    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}";
    }
}

For instance, one of my foreign key tables looks like this:例如,我的一个外键表如下所示:

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

And this is my code in my repository class这是我存储库中的代码 class

private const string SqlGetAllPC = @"Select PC.PC_ID, PC.PC_NAME,
     PC_BRAND.PC_BRAND,PC_MODEL.PC_MODEL,PC_NET.
     PC_NET,PC_OS.PC_OS,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";

    public IEnumerable<PC> GetAllFromPc()
    {
        IEnumerable<PC> list = null;
        try
        {
            connector.OpenConnection();
            System.Data.DataTable data = connector.GetData(SqlGetAllPC);
            if (data != null && data.Rows.Count > 0)
            {
                list = ConvertToPC(data);
            }
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            connector.CloseConnection();
        }
        return list;
    }

    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_SERIAL = row.Field<string>(1),
                PC_NAME = row.Field<string>(2),
                PC_BRAND_ID = row.Field<int>(3),
                PC_MODEL_ID = row.Field<int>(4),
                PC_OS_ID = row.Field<int>(5),
                PC_NET_ID = row.Field<int>(6),
                PC_RAM_ID = row.Field<int>(7),
            });
        }
        return tmp;
    }
}

And at last my button that retrieves the data最后是我检索数据的按钮

private void GetAllButton(object sender, RoutedEventArgs e)
{
   Data.Repositories.PCRepository newpc = new Data.Repositories.PCRepository();
   IEnumberable<Data.Model.PC> data = newpc.GetAllFromPc();
   if (data != null)
   {
       StringBuilder sb = new StringBuilder();
       data.ToList()
           .ForEach(x=> sb.AppendLine(x.ToString()))
       MessageBox.Show(sb.ToString());
   }
}

With some editing I was able to retrieve from my PC tabel.通过一些编辑,我能够从我的 PC 标签中检索。 But I also want to retrieve the PC's model/brand name from the PC_Brand and PC_Model table in my database.但我还想从数据库中的 PC_Brand 和 PC_Model 表中检索 PC 的型号/品牌名称。 在此处输入图像描述

Your SELECT is reading what I take to be string values (PC_MODEL.PC_MODEL, PC.NET.PC.NET, PC_OS.PC_OS, PC_RAM.PC_RAM), but you are assigning them to integers, hence the invalid cast.您的SELECT正在读取我认为是字符串值的内容(PC_MODEL.PC_MODEL、PC.NET.PC.NET、PC_OS.PC_OS、PC_RAM.PC_RAM),但您将它们分配给整数,因此转换无效。

Why am I sure that these are strings?为什么我确定这些是字符串? Because of your joins.因为你的加入。 You are joining on eg PC_MODEL_ID which are almost certainly integers.您正在加入,例如 PC_MODEL_ID,它几乎肯定是整数。

Change your SELECT to:将您的SELECT更改为:

SELECT PC.PC_ID, PC.PC_NAME, PC_BRAND.PC_BRAND,PC.PC_MODEL_ID, PC.PC_NET_ID, PC.PC_OS_ID,PC.PC_RAM_ID
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

Note that you do not need all the other joins, if you are only selecting the integer values.请注意,如果您只选择 integer 值,则不需要所有其他联接。

EDIT编辑

The you need to change your select to您需要将 select 更改为

SELECT PC.PC_ID, PC.PC_SERIAL, PC.PC_NAME, 
PC_BRAND.PC_BRAND, PC.PC_BRAND_ID, 
PC_MODEL.PC_MODEL, PC.PC_MODEL_ID, 
PC_NET.PC_NET, PC.PC_NET_ID, 
PC_OS.PC_OS, PC.PC_OS_ID, 
PC_RAM.PC_RAM, PC.PC_RAM_ID 
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

Now you can do something like this in ConvertToPC:现在您可以在 ConvertToPC 中执行类似的操作:

private static 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_SERIAL = row.Field<string>(1),
            PC_NAME = row.Field<string>(2),
            PC_Brand = new PCBrand
            {
                PC_BRAND = row.Field<string>(3),
                PC_BRAND_ID = row.Field<int>(4)
            },
            PC_BRAND_ID = row.Field<int>(4),
            PC_Model = new PCModel
            {
                PC_MODEL = row.Field<string>(5),
                PC_MODEL_ID = row.Field<int>(6)
            },
            PC_MODEL_ID = row.Field<int>(6),
            PC_Net = new PCNet
            {
                PC_NET = row.Field<string>(7),
                PC_NET_ID = row.Field<int>(8)
            },
            PC_NET_ID = row.Field<int>(8),
            PC_OS = new PCOS
            {
                PC_OS = row.Field<string>(9),
                PC_OS_ID = row.Field<int>(10)
            },
            PC_OS_ID = row.Field<int>(10),
            PC_Ram = new PCRam
            {
                PC_RAM = row.Field<string>(11),
                PC_RAM_ID = row.Field<int>(12)
            },
            PC_RAM_ID = row.Field<int>(12)
        });
    }
    return tmp;
}

Please note that I have changed your code by as little as possible.请注意,我已尽可能少地更改您的代码。 In practice I would do a lot of things very differently.在实践中,我会做很多不同的事情。 For example, all the foreign key ids are now duplicated: instead of having both an object of type PCModel and an int PC_MODEL_ID in your PC class, you only need the object PCModel, because it already contains the ID.例如,现在所有外键 ID 都是重复的:您的 PC class 中不再同时具有 PCModel 类型的 object 和 int PC_MODEL_ID,您只需要 object PCModel,因为它已经包含 ID。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从c#中的sql中检索特定数据? - How can I retrieve specific data from sql in c#? 如何使用C#从SQL检索二进制数据? - How can I retrieve binary data from sql with c#? 使用详细信息表中的外键将数据从C#插入到SQL Server 2005中的主/明细表中 - Insert Data to Master/Detail table in SQL Server 2005 from C# with Foreign key in Detail table 在c#应用程序中,如何在SQL中连接子任务表的外键? - In c# app, how to connect foreign key of subtask table in SQL? 如何使用 C# 从 SQL 服务器检索点? - How can I retrieve a Point from SQL Server with C#? 如何在C#中为表设置外键? - How to set a foreign key for a table in C#? C#/ WPF如何从文本框读取“绑定”(数据从SQL表获取)? - C#/WPF How can I read “Bindings” from a TextBox (Data gets from a SQL-Table)? 如何使用 c# 将 JSON 数据从 web api 导入 SQL 表? - How can I import JSON data from web api into SQL table using c#? 实体框架使用外键从表中检索数据 - Entity Framework retrieve data from table with foreign key 如何在C#中与SQL数据库表之间来回存储和检索数组 - How to store and retrieve an array to and from SQL database table in c#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM