Для проекта 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 /
И у меня есть несколько дополнительных вопросов, которые, я надеюсь, вы можете мне помочь / указать мне правильное направление:
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, все еще активна в конце пакета. Транзакция откатывается».
Но это ПЕРВЫЙ запрос выполнен!