Сохранение и извлечение файлов из базы данных

Последнее обновление: 11.02.2021

Создание базы данных и таблицы для ханения файлов

Рассмотрим, как мы можем сохранять файлы, в частности, файлы изображений в базу данных. Для этого создадим новую базу данных и в ней новую таблицу Files с четырьмя столбцами:

  • Id - первичный ключ и идентификатор, имеет тип int)

  • FileName будет хранить имя файла и имеет тип nvarchar

  • Title будет хранить заголовок файла и также имеет тип nvarchar

  • ImageData будет содержать бинарные данные файла и имеет тип varbinary(MAX)

Для создания базы данных и таблицы для хранения файлов определим следующую программу:

using System;
using System.Threading.Tasks;
using Microsoft.Data.SqlClient;

namespace HelloApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            string connectionString = "Server=(localdb)\\mssqllocaldb;Database=master;Trusted_Connection=True;";
            string sqlExpression = "CREATE DATABASE filesdb";
            // создаем базу данных
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                await connection.OpenAsync();
                SqlCommand command = new SqlCommand(sqlExpression, connection);
                await command.ExecuteNonQueryAsync();
                Console.WriteLine("База данных создана");
            }

            connectionString = "Server=(localdb)\\mssqllocaldb;Database=filesdb;Trusted_Connection=True;";
            sqlExpression = @"CREATE TABLE Files 
                                (Id INT PRIMARY KEY IDENTITY, 
                                 Title NVARCHAR(50) NOT NULL, 
                                 FileName NVARCHAR(50) NOT NULL,
                                 ImageData varbinary(MAX))";
            // создаем таблицу
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                await connection.OpenAsync();
                SqlCommand command = new SqlCommand(sqlExpression, connection);
                await command.ExecuteNonQueryAsync();
                Console.WriteLine("Таблица Files создана");
            }

            Console.Read();
        }
    }
}

Сохранение файлов

Определим код, в котором будут загружаться данные в таблицу:

using System;
using System.Data;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Data.SqlClient;

namespace HelloApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            await SaveFileToDatabaseAsync();
            Console.Read();
        }

        private static async Task SaveFileToDatabaseAsync()
        {
            string connectionString = "Server=(localdb)\\mssqllocaldb;Database=filesdb;Trusted_Connection=True;";
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                await connection.OpenAsync();
                SqlCommand command = new SqlCommand();
                command.Connection = connection;
                command.CommandText = @"INSERT INTO Files VALUES (@FileName, @Title, @ImageData)";
                command.Parameters.Add("@FileName", SqlDbType.NVarChar, 50);
                command.Parameters.Add("@Title", SqlDbType.NVarChar, 50);
                
                // путь к файлу для загрузки
                string filename = @"D:\forest.jpg";
                // заголовок файла
                string title = "Лес";
                // получаем короткое имя файла для сохранения в бд
                string shortFileName = filename.Substring(filename.LastIndexOf('\\') + 1); // forest.jpg
                                                                                           
                // массив для хранения бинарных данных файла
                byte[] imageData;
                using (FileStream fs = new FileStream(filename, FileMode.Open))
                {
                    imageData = new byte[fs.Length];
                    fs.Read(imageData, 0, imageData.Length);
                    command.Parameters.Add("@ImageData", SqlDbType.Image, Convert.ToInt32(fs.Length));
                }
                // передаем данные в команду через параметры
                command.Parameters["@FileName"].Value = shortFileName;
                command.Parameters["@Title"].Value = title;
                command.Parameters["@ImageData"].Value = imageData;

                await command.ExecuteNonQueryAsync();
                Console.WriteLine("Файл сохранен");
            }
        }
    }
}

После выполнения этой программы в базе данных появится соответствующая запись:

Сохранение изображений в базе данных MS SQL Server в C# и .NET

Хотя в данном случае загружается изображение, но это частный случай, в принципе можно использовать и другие типы файлов.

Извлечение файлов из базы данных

Теперь произведем обратную операцию - получим файл из БД. Вначале определим класс файла, который упростит работу с данными:

public class Image
{
    public Image(int id, string filename, string title, byte[] data)
    {
        Id = id;
        FileName = filename;
        Title = title;
        Data = data;
    }
    public int Id { get; private set; }
    public string FileName { get; private set; }
    public string Title { get; private set; }
    public byte[] Data { get; private set; }
}

Затем в коде программы определим следующий метод:

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Data.SqlClient;

namespace HelloApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            await ReadFileFromDatabaseAsync();
            Console.Read();
        }

        private static async Task ReadFileFromDatabaseAsync()
        {
            string connectionString = "Server=(localdb)\\mssqllocaldb;Database=filesdb;Trusted_Connection=True;";
            List<Image> images = new List<Image>();
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                await connection.OpenAsync();
                string sql = "SELECT * FROM Files";
                SqlCommand command = new SqlCommand(sql, connection);
                using (SqlDataReader reader = await command.ExecuteReaderAsync())
                {
                    while (await reader.ReadAsync())
                    {
                        int id = reader.GetInt32(0);
                        string filename = reader.GetString(1);
                        string title = reader.GetString(2);
                        byte[] data = (byte[])reader.GetValue(3);

                        Image image = new Image(id, filename, title, data);
                        images.Add(image);
                    }
                }   
            }
            // сохраним первый файл из списка
            if (images.Count > 0)
            {
                using (FileStream fs = new FileStream(images[0].FileName, FileMode.OpenOrCreate))
                {
                    fs.Write(images[0].Data, 0, images[0].Data.Length);
                    Console.WriteLine($"Файл {images[0].Title} сохранен");
                }
            }
        }
    public class Image
    {
        public Image(int id, string filename, string title, byte[] data)
        {
            Id = id;
            FileName = filename;
            Title = title;
            Data = data;
        }
        public int Id { get; private set; }
        public string FileName { get; private set; }
        public string Title { get; private set; }
        public byte[] Data { get; private set; }
    }
}

В этом методе с помощью SqlDataReader мы получаем значения из БД и по ним создаем объект Image, который потом добавляется в список. И в конце смотрим, если в списке есть элементы, то берем первый элемент и сохраняем его на локальный компьютер. И после сохранения в папке нашей программы появится загруженный из базы данных файл.

Извлечение файлов из базе данных MS SQL Server в C# и .NET
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850