Đối với dự án asp.Net MVC, tôi sẽ cần xử lý các tệp lớn (chủ yếu là 200-300Mo, đôi khi 1Go).Ứng dụng lớp: Lưu trữ tập tin trong dòng phim trong cơ sở dữ liệu
Tôi sẽ lưu trữ chúng trong cơ sở dữ liệu (vì lý do sao lưu/lý do nhất quán).
Tôi lo ngại về vấn đề hiệu suất, vì vậy tôi muốn tránh tất cả những gì có thể để có một mảng byte ở bất cứ đâu trong chương trình, mục tiêu là làm việc với luồng mọi nơi.
Tôi là một ứng dụng phân lớp, chủ yếu có nghĩa là tôi có một vài "DataStore", chịu trách nhiệm kết nối và truy xuất/chèn/cập nhật dữ liệu từ cơ sở dữ liệu.
Vì EF hiện không hỗ trợ Filestream, tôi đang xử lý "Phần tệp" thông qua các yêu cầu Sql đơn giản. Tôi đã đọc một bài viết tốt về FileStream sử dụng ở đây: http://blog.tallan.com/2011/08/22/using-sqlfilestream-with-c-to-access-sql-server-filestream-data/
Và tôi đã một số câu hỏi bổ sung, mà tôi hy vọng bạn có thể giúp tôi/điểm tôi vào hướng tốt:
- Kể từ khi tôi đã một ứng dụng lớp, một khi tôi đã khởi tạo đối tượng SQLFileStream của tôi, tôi có thể loại bỏ phạm vi SqlCommand/Sql Connection/Transaction không?
- Nếu không, tôi phải đóng chúng như thế nào?
- Trong liên kết trước, có một ví dụ minh họa cách sử dụng nó với ASP. Nhưng kể từ khi tôi đang sử dụng ASP.Net MVC, không phải là có một người trợ giúp đó là trực tiếp có thể dòng một tập tin vào trình duyệt? Bởi vì tôi đã tìm thấy nhiều ví dụ về dữ liệu nhị phân trả về cho trình duyệt, nhưng hiện tại, tất cả các ví dụ tôi tìm được về cơ bản giống như
Stream.ToArray()
để điền vào một mảng byte và trả về trình duyệt. Tôi thấy rằng tôi có thể trả về một sốFileStreamResult
có thể tham số aStream
. Đó có phải là hướng đi đúng không?
(Tôi hiện không liên quan bằng cách tải lên các tập tin lớn, kể từ khi họ được chèn vào bởi một ứng dụng nặng trong cơ sở dữ liệu)
EDIT
(Xin lỗi vì mã bẩn, nó chỉ không có 50 phương pháp khác nhau ở đây Tôi đã thử thêm một chút và tôi hiện đang mắc kẹt với phần "đã đọc", vì phần tách rời (nơi chúng tôi tạo lớp và nơi chúng tôi sử dụng nó):
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);
Nhưng tôi nhận được ngoại lệ tại rdr.GetSqlBinary(1).Value
vì GET_FILESTREAM_TRANSACTION_CONTEXT trả về giá trị rỗng. Tôi đã tìm thấy here rằng đây là do giao dịch bị thiếu.
Tôi đã thử với một "TransactionScope" + cuộc gọi .Complete();
của nó. Không thay đổi gì cả.
tôi đã cố gắng để làm một GIAO DỊCH BEGIN như cho thấy trong liên kết theo thời gian:
SqlConnection connection = GetConnection(); connection.Open(); SqlCommand cmd = new 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 = new SqlCommand(); cmd.CommandText = "COMMIT TRANSACTION"; cmd.CommandType = CommandType.Text; cmd.Connection = connection; cmd.ExecuteNonQuery();
Nhưng nó bị treo trên "ExecuteNonQuery" đầu tiên với ngoại lệ "A transaction that was started in a MARS batch is still active at the end of the batch. The transaction is rolled back."
Nhưng đó là truy vấn FIRST được thực hiện!
Tôi có thể nói đây là nhiệm vụ phù hợp hơn với hệ thống tệp, vì bạn đang xử lý tệp. Giả sử trang web/cơ sở dữ liệu được triển khai trên một máy tính Windows, một thay thế để xem xét có thể là Giao dịch NTFS. Nó thậm chí phải tích hợp với các giao dịch khác bằng DTM. Tho thừa nhận rằng có một số của gotcha (ví dụ, hỗ trợ chia sẻ tập tin xấu). 1 vì không sử dụng byte [] :) –