Многоуровневое приложение: хранить файл в потоке файлов в базе данных

Для проекта asp.Net MVC мне нужно будет обрабатывать большие файлы (в основном 200-300Mo, иногда 1Go).

Я сохраню их в базе данных (для резервных копий / соображений согласованности).

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

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

Поскольку EF на данный момент не поддерживает Filestream, я обрабатываю «файловую часть» с помощью простых запросов Sql. Я прочитал здесь хорошую статью об использовании файлового потока: http://blog.tallan.com/2011/08/22/using-sqlfilestream-with-c-to-access-sql-server-filestream-data /

И у меня есть несколько дополнительных вопросов, которые, я надеюсь, вы можете мне помочь / указать мне правильное направление:

  • Поскольку у меня многоуровневое приложение, после создания экземпляра объекта SQLFileStream, могу ли я избавиться от SqlCommand / Sql Connection / Transaction scope?
  • Если нет, как я должен их закрыть?
  • В предыдущей ссылке есть пример, который показывает, как использовать его с ASP. Но поскольку я использую ASP.Net MVC, разве нет помощника, который может напрямую передавать файл в браузер? Потому что я нашел много примеров возврата двоичных данных в браузер, но на данный момент все примеры, которые я нашел, делают в основном что-то вроде Stream.ToArray () , чтобы заполнить массив байтов и вернуть его в браузер. Я обнаружил, что могу вернуть FileStreamResult , который может принимать в параметре Stream . Это правильное направление?

(В настоящее время меня не интересует загрузка больших файлов, поскольку они вставляются тяжелым клиентом в базу данных)

РЕДАКТИРОВАТЬ

(Извините за грязный код, это только для здесь нет 50 различных методов. Я сделал еще несколько попыток и в настоящее время застрял на части "чтения" из-за отдельной части (где мы генерируем слой и где мы его потребляем):

        SqlConnection conn = GetConnection();
        conn.Open();
        SqlCommand cmd = new SqlCommand(_selectMetaDataRequest, conn);
        cmd.Parameters.Add(_idFile, SqlDbType.Int).Value = idFile;
        SqlDataReader rdr = cmd.ExecuteReader();
        rdr.Read();
        string serverPath = rdr.GetSqlString(0).Value;
        byte[] serverTxn = rdr.GetSqlBinary(1).Value;
        rdr.Close();
        return new SqlFileStream(serverPath, serverTxn, FileAccess.Read);

Но я получаю исключение на ] rdr.GetSqlBinary (1) .Value , потому что GET_FILESTREAM_TRANSACTION_CONTEXT возвращает значение null. Я обнаружил здесь , что это связано с отсутствующей транзакцией.

Я пробовал использовать TransactionScope + его вызов .Complete (); . Ничего не меняет.

Я попытался выполнить НАЧАЛО ТРАНЗАКЦИИ, как показано в предыдущей ссылке:

  SqlConnection connection = GetConnection ();
connection.Open ();
SqlCommand cmd = новый SqlCommand ();
        cmd.CommandText = "BEGIN TRANSACTION";
        cmd.CommandType = CommandType.Text;
        cmd.Connection = connection;
        cmd.ExecuteNonQuery();

        cmd = new SqlCommand(_selectMetaDataRequest, connection);
        cmd.Parameters.Add(_idFile, SqlDbType.Int).Value = idFile;
        SqlDataReader rdr = cmd.ExecuteReader();
        rdr.Read();
        string serverPath = rdr.GetSqlString(0).Value;
        byte[] serverTxn = rdr.GetSqlBinary(1).Value;
        rdr.Close();
        SqlFileStream sqlFileStream = new SqlFileStream(serverPath, serverTxn, FileAccess.Read);
  cmd = новый SqlCommand ();
cmd.CommandText = "ЗАВЕРШИТЬ СДЕЛКУ";
cmd.CommandType = CommandType.Text;
cmd.Connection = соединение;
cmd.ExecuteNonQuery ();

Но происходит сбой при первом «ExecuteNonQuery» за исключением «Транзакция, начатая в пакете MARS, все еще активна в конце пакета. Транзакция откатывается». Но это ПЕРВЫЙ запрос выполнен!

5
задан J4N 23 January 2012 в 13:15
поделиться