Строка Base64 сохраняется в базе данных как null C#

#c# #database #winforms #entity-framework #tobase64string

Вопрос:

У меня проблема, когда я конвертирую изображение в строку Base64 и сохраняю его как строку в базе данных, но оно ничего не возвращает. Base64Text-глобальная переменная, также переменная не равна нулю, я проверил ее с помощью кнопки для заполнения текстового поля, она просто сохраняется как «» в базе данных.

Вот модель таблицы в базе данных

     public class Product
    {
        public int Id { get; set; }
        public string ProductName { get; set; }
        public double ProductPrice { get; set; }
        public int ProductAmount { get; set; }
        public string ProductImage { get; set; } // Used for storing image string
        public int userID { get; set; }
    }
 
 // Here is image converter
        private void btnAddImage_Click(object sender, EventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "Image Files(*.BMP;*.JPG;*.PNG;*.JPEG)|*.BMP;*.JPG;*.PNG;*.JPEG"  
                "|All files(*.*)|*.*";
            dialog.CheckFileExists = true;
            dialog.Multiselect = false;
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                var image = new Bitmap(dialog.FileName);
                pictureBoxProductImage.Show();
                pictureBoxProductImage.Image = (Image)image;

                byte[] imageArray = System.IO.File.ReadAllBytes(dialog.FileName);
                base64Text = Convert.ToBase64String(imageArray);
            }
        }
 
 // Here is saving image using Entity framework
        private void btnAddProduct_Click(object sender, EventArgs e)
        {
            string imagePath = base64Text;
            if (txtBoxProductName.Text == null || txtBoxProductPrice.Text == null || txtBoxProductQuantity.Text == null || imagePath == null || imagePath == "")
            {
                MessageBox.Show("Please fill required information!", "", MessageBoxButtons.OK);
            }
            else
            {
                model.ProductName = txtBoxProductName.Text;
                model.ProductPrice = Convert.ToDouble(txtBoxProductPrice.Text);
                model.ProductAmount = Convert.ToInt32(txtBoxProductQuantity.Text);
                model.ProductImage = imagePath;
                model.userID = id;

                using (var context = new ProductContext())
                {
                    context.Products.Add(model);
                    context.SaveChanges();
                }
                MessageBox.Show("Product sucesffuly added to database!", "", MessageBoxButtons.OK);
                Clear();
            }
        }
 

Комментарии:

1. На первый взгляд я заметил, что вы преобразуете все изображение в base64, а не только путь! Во-вторых, не могли бы вы показать нам DbContext? и вы просматривали содержимое базы данных после операции сохранения?

2. Все остальные данные были сохранены правильно, как написано, ожидайте, что строка изображения будет»», поэтому мне нужен путь сохранения, а не строка base64?

3. Можете ли вы предоставить дополнительную информацию о том, на какую версию EF вы ориентируетесь и какую базу данных вы используете? binaryintellect.net/articles/… Я бы предложил следовать приведенному выше примеру… обратите особое внимание на конфигурацию сущности и массив байтов из потока памяти, скопированного в метод

4. Где вы создаете экземпляр сущности продукта? возможно, вы установили его свойство image где-то в другом месте после его сохранения, и EF все еще отслеживает этот объект, и в другой транзакции сохранения он сбрасывается до нуля

5. Поскольку вы сохраняете все изображение в качестве base64, а не только путь, я думаю, что вы можете достичь некоторого предела в своей таблице, так как результат base64 будет длинным. Я рекомендую вам сохранить только путь или использовать другой тип данных для хранения двоичного файла-если файл недоступен локально на всех компьютерах или недоступен онлайн-.

Ответ №1:

Похоже, вы опасно смешиваете переменные области. Учитывая этот код:

 model.ProductName = txtBoxProductName.Text;
model.ProductPrice = Convert.ToDouble(txtBoxProductPrice.Text);
model.ProductAmount = Convert.ToInt32(txtBoxProductQuantity.Text);
model.ProductImage = imagePath;
model.userID = id;

using (var context = new ProductContext())
{
    context.Products.Add(model);
    context.SaveChanges();
}
 

«модель» не относится к этому методу.

Я не рекомендую привязывать представления к сущностям в качестве моделей представлений, вместо этого используйте простой старый класс C# ViewModel, чтобы избежать путаницы и проблем с объектами, вызывающими множество проблем. (Отслеживание изменений свойств, поведение проверки пользовательского интерфейса и т.д.)

На что это должно больше походить:

 using (var context = new ProductContext())
{
    var product = new Product
    {
        UserId = id,
        ProductName = txtBoxProductName.Text,
        ProductPrice = Convert.ToDouble(txtBoxProductPrice.Text),
        ProductAmount = Convert.ToInt32(txtBoxProductQuantity.Text),
        ProductImage = hiddenImage.Text, // Something in the scope of the view storing the image Base64 content, not a global variable.
    };
    context.Products.Add(product);
    context.SaveChanges();
}
 

При добавлении сущности вы хотите убедиться, что имеете дело с новым экземпляром этой сущности, а не со ссылкой. model это может быть ссылка на другую сущность, которую контекст уже отслеживает, что означает, что вы можете в конечном итоге заменить значения в совершенно другой записи, когда думаете, что добавляете новую строку. Кроме того, поскольку вы определяете область действия нового экземпляра DbContext, любая ссылка на сущность за пределами этой области может привести к исключениям.

Избегайте глобальных переменных для любых деталей. При выборе изображения убедитесь, что Base64 хранится где-то в области страницы приложения или модели связанного представления. Если после этих изменений по-прежнему не сохраняется ProductImage, я бы посмотрел на объявление сущности , чтобы убедиться, что оно не помечено как Ignore , и рассмотрел возможность использования профилировщика для проверки создаваемого SQL, чтобы убедиться, что поле включено и какое значение отправляется.