C# Select 来自 SQL table 的所有图像到所有图片框

C# Select all Images from SQL table into all pictureboxes

我想使用来自 SQL 的代码:SELECT * FROM USERS 这个 table 包含图像,我想对每个用户应用所有图像。 我正在使用用户控件,每个用户控件都有用户详细信息、姓名、姓氏和图像。

我试图从我的 table 中填充图像,但我在所有用户控件图片框中都得到了相同的图像。

    private void populateItems()
    {
        string query = "SELECT * FROM Users";
        {
            using (SqlDataAdapter sda = new SqlDataAdapter(query, con))
            {
                //Fill the DataTable with records from Table.
                DataTable dt = new DataTable();
                sda.Fill(dt);

                //Loop and add SelectUser:Usercontrol to FloyLayoutPanel.
                foreach (DataRow row in dt.Rows)
                {
                    SelectContacts contact = new SelectContacts();
                    contact.FirstName = row["FirstName"].ToString();
                    contact.LastName = row["LastName"].ToString();
                    contact.Title = row["Title"].ToString();

                    byte[] img = (byte[])dt.Rows[0]["Image"];
                    MemoryStream ms = new MemoryStream(img);
                    contact.PublicProfilePic = Image.FromStream(ms);

                    flowUsers.Controls.Add(contact);
                }
            }
        }
    }

它应该向我显示与用户相关的不同图片。 但相反,我在所有图片框中获得了第一个可用图像。

如何针对单个用户填充单个图像?

您只是在这里收集第一张图片:

byte[] img = (byte[])dt.Rows[0]["Image"];

将该行代码更改为

byte[] img = (byte[])row["Image"];

并且有很多方法可以避免空错误:

// Using "as" keyword is the best practice only
// in case you are doing null check after the cast
byte[] img = row["Image"] as byte[];
// OR the following will either give you the image or an empty byte array.
byte[] img = row["Image"] as byte[] ?? new byte[];

但始终记得检查空值,以免出现任何错误。

完整代码应如下所示:

private void populateItems()
{
    string query = "SELECT * FROM Users";
    {
        using (SqlDataAdapter sda = new SqlDataAdapter(query, con))
        {
            //Fill the DataTable with records from Table.
            DataTable dt = new DataTable();
            sda.Fill(dt);

            //Loop and add SelectUser:Usercontrol to FloyLayoutPanel.
            foreach (DataRow row in dt.Rows)
            {
                SelectContacts contact = new SelectContacts();
                contact.FirstName = row["FirstName"].ToString();
                contact.LastName = row["LastName"].ToString();
                contact.Title = row["Title"].ToString();

                byte[] img = row["Image"] as byte[];

                if(img != null && img.length > 0)
                {
                    MemoryStream ms = new MemoryStream(img);
                    contact.PublicProfilePic = Image.FromStream(ms);
                }

                flowUsers.Controls.Add(contact);
            }
        }
    }
}

下一行的 0 是罪魁祸首。

byte[] img = (byte[])dt.Rows[0]["Image"];

使用

byte[] img = (byte[])row["Image"];

而不是使用

dt.Rows[0]["Image"]

使用:

row["Image"]

目前您只能访问结果中第一行的图像。上面的更改将为每一行提供给您。

这是因为您从此处的行对象中获取第一行

byte[] img = (byte[])dt.Rows[0]["Image"];

既然你在数据库中允许空值,试试这样的事情,

if(!Convert.IsDBNull(row["Image"])) { 
   byte[] img = (byte[])row["Image"];                     
   MemoryStream ms = new MemoryStream(img);
   contact.PublicProfilePic = Image.FromStream(ms);
}

在 for-each 循环中,您不是获取相应的行(用户)图像,而是获取第一个用户的图像以供其余所有用户使用。 在每次迭代中取 row["image"] NOT dt.Rows[0]["Image"].

对于空值的检查,可以使用下面的经典方式

object value = row["Image"];
    if (value == DBNull.Value)
    {

    }
    else
    {
    }

或者使用三元运算符。

int? myValue = (Convert.IsDBNull(row["column"]) ? null : (int?) Convert.ToInt32(row["column"]));