即使图像未更改,如何更新数据库记录

How to update database records even if the image is not changed

我正在使用 localDB 作为我的数据库。

我有一个员工table,员工图片存储在另一个table

这是我创建和更新的存储过程:

    IF NOT EXISTS (SELECT * 
                   FROM   dbo.Employee 
                   WHERE  employee_id=@employee_id)   
    BEGIN TRY
        BEGIN TRAN
            INSERT INTO dbo.Employee 
            (employee_name,
             city,
             department,
             gender
            )  
            OUTPUT inserted.employee_id 
            INTO   @employee_id_PK (employee_id) 
            VALUES 
            (@employee_name,
             @city,
             @department,
             @gender
            )  
            
            SELECT @FK_Employee_Image_To_Employee_Table = employee_id 
            FROM   @employee_id_PK 
            INSERT INTO dbo.Employee_Image
            (user_image,
             file_extension,
             employee_id
            )
            VALUES
            (@user_image,
             @file_extension,
             @FK_Employee_Image_To_Employee_Table
            )
        COMMIT TRAN 
    END TRY

    BEGIN CATCH
        IF @@TRANCOUNT > 0
            ROLLBACK TRAN --RollBack in case of Error
        RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
    END CATCH
            

    ELSE  
    BEGIN TRY
        BEGIN TRAN
            UPDATE e
            SET    e.employee_name=@employee_name,
                  e.city=@city,
                  e.department=@department,  
                  e.gender=@gender
            FROM   dbo.Employee e, dbo.Employee_Health_Insurance h
            WHERE  e.employee_id=@employee_id AND h.employee_id=@employee_id
                                                                         
            UPDATE i
            SET    i.user_image=@user_image,
                  i.file_extension=@file_extension
            FROM   dbo.Employee_Image i, dbo.Employee e
            WHERE  i.employee_id=@employee_id AND e.employee_id=@employee_id
        COMMIT TRAN
    END TRY

    BEGIN CATCH
        IF @@TRANCOUNT > 0
            ROLLBACK TRAN --RollBack in case of Error
        RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
    END CATCH 


这是我通过 C# 添加记录的方式

using (SqlConnection con = new SqlConnection(connectionStringConfig))
using (SqlCommand sqlCmd = new SqlCommand("spCreateOrUpdateData", con))
{
try
{
    con.Open();
    sqlCmd.CommandType = CommandType.StoredProcedure;

    //Employee Record
    sqlCmd.Parameters.Add("@employee_id", SqlDbType.NVarChar).Value = EmployeeId;
    sqlCmd.Parameters.Add("@employee_name", SqlDbType.NVarChar, 250).Value = txtEmpName.Text;
    sqlCmd.Parameters.Add("@city", SqlDbType.NVarChar, 50).Value = txtEmpCity.Text;
    sqlCmd.Parameters.Add("@department", SqlDbType.NVarChar, 50).Value = txtEmpDept.Text;
    sqlCmd.Parameters.Add("@gender", SqlDbType.NVarChar, 6).Value = cboEmpGender.Text;

    //Employee Image 
    sqlCmd.Parameters.Add("@user_image", SqlDbType.VarBinary, 8000).Value = ConvertImageToByteArray(pictureBox1.Image); <-----------------error here according to StackTrace
    sqlCmd.Parameters.Add("@file_extension", SqlDbType.VarChar, 12).Value = lblFileExtension.Text;

    int numRes = sqlCmd.ExecuteNonQuery();
    string ActionType = (btnSave.Text == "Save") ? "Saved" : "Updated";
    if (numRes > 0)
    {
        MessageBox.Show($"{ txtEmpName.Text }'s record is { ActionType } successfully !!!");
        RefreshData();
    }
    else
        MessageBox.Show($"{txtEmpName.Text} Already Exist !!!");
}
catch (Exception ex)
{
    MessageBox.Show($"Cannot INSERT or UPDATE data! \nError: { ex.Message }");
}

这就是我将图像转换为 byte[] 数组的方式:

byte[] ConvertImageToByteArray(Image img)
{
    //with memory stream:
    /*[1]
    using (MemoryStream ms = new MemoryStream())
    {
        img.Save(ms, img.RawFormat);<-----------------error here according to StackTrace
        return ms.ToArray();
    }*/

    /*[2]
    using (MemoryStream ms = new MemoryStream())
    {
        img.Save(ms, img.RawFormat);<-----------------error here according to StackTrace
        byte[] arrImage = ms.GetBuffer();
        return arrImage;
    }*/


    // with image converter
    /*ImageConverter converter = new ImageConverter();
    return (byte[])converter.ConvertTo(img, typeof(byte[]));*/ <-------------error here according to StackTrace
}

我在将图像转换为字节数组时尝试了上面的代码,当我 INSERT 它到数据库时它是成功的,但是当我 UPDATE 记录(例如更改“员工姓名”)而不更改图像将显示错误:“GDI+ 发生一般错误。”

编辑:

是否与检索图像有关?

我没有在我的 datagridview 上显示我的图像二进制数据,但我 display/retreive 我的图像是这样的:

private void dgvEmpDetails_CellClick(object sender, DataGridViewCellEventArgs e)
{
    try
    {
        if (e.RowIndex != -1)
        {
            DataGridViewRow row = dgvEmpDetails.Rows[e.RowIndex];
            EmployeeId = row.Cells[0].Value?.ToString();             
            txtEmpName.Text = row.Cells[1].Value?.ToString();
            txtEmpCity.Text = row.Cells[2].Value?.ToString();
            txtEmpDept.Text = row.Cells[3].Value?.ToString();
            cboEmpGender.Text = row.Cells[4].Value?.ToString();

            //Display user image
            using (SqlConnection con = new SqlConnection(connectionStringConfig))
            using (SqlCommand sqlCmd = new SqlCommand("SELECT user_image, file_extension FROM dbo.Employee_Image WHERE employee_id=@employee_id", con))
            {
                con.Open();
                sqlCmd.Parameters.Add("@employee_id", SqlDbType.NVarChar).Value = EmployeeId;

                using (SqlDataReader reader = sqlCmd.ExecuteReader())
                {
                    if (reader.HasRows)
                    {
                        reader.Read();
                        pictureBox1.Image = ConvertByteArrayToImage((byte[])(reader.GetValue(0))); <------------- displaying the image here
                        lblFileExtension.Text = reader.GetValue(1).ToString();
                    }
                    else
                    {
                        pictureBox1.Image = null;
                    }
                }
            }
            btnSave.Text = "Update";
            btnDelete.Enabled = true;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show($"Something is wrong with the selected record! \nError: { ex.GetType().FullName }");
    }
}

我的字节数组转图片的方法:

public static Image ConvertByteArrayToImage(byte[] byteArrayIn)
{
    using (MemoryStream ms = new MemoryStream(byteArrayIn))
    {
        Image returnImage = Image.FromStream(ms);
        return returnImage;
    }
}

我已经通过修改这个方法解决了这个问题:

这是我将图片从 pictureBox 转换为字节的代码[]:

public static byte[] ImageToBytes(Image userImage)//Get bytes of the image
{
    using (MemoryStream ms = new MemoryStream())
    using (Bitmap tempImage = new Bitmap(userImage))
    {
        /*copy the object (userImage) into a new object (tempImage), 
            then use that object(tempImage) to "Write" */
        tempImage.Save(ms, userImage.RawFormat);
        return ms.ToArray();
    }
}

这是我的代码,用于从数据库转换图像的二进制数据并将其加载到我的 pictureBox:

public static Image BytesToImage(byte[] buffer) //Get image from database
{
    using (MemoryStream ms = new MemoryStream(buffer))
    {
        return Image.FromStream(ms);
    }
}

这是我从数据库中获取图像的方法

   // This method use to update the form.
    private void loadFormWithID(int ID)
    {
        dbServer conn = new dbServer(sysController.getConn);
        DataTable tbl = conn.getQueryList("SELECT * FROM Products WHERE ID = " + ID);
        DataRow row = tbl.Rows[0];      
        // This is how i update the Picture Box
        pictureBoxItem.Image = row["Image"] == DBNull.Value ? pictureBoxItem.InitialImage : ImageController.bytesToImage((byte[])row["Image"]);  
     }

这是我的数据库服务器 class,它与数据库通信。

   public class dbServer
   {
        public string _connectionLink;

        public dbServer(string connectionString)
        {
            _connectionLink = connectionString; 
        }

        public DataTable getQueryList(string sqlQuery)
        {
             DataTable tbl = new DataTable();

           using (SqlConnection conn = new SqlConnection(_connectionLink))
           {
               using (SqlCommand cmd = new SqlCommand(sqlQuery, conn))
                {
                   conn.Open();
                   SqlDataReader reader = cmd.ExecuteReader();
                   tbl.Load(reader);
                }
            }
            return tbl;
        }
   }

我希望这能解决问题。