Tôi đang cố gắng sử dụng Fluent NHibernate để di chuyển cơ sở dữ liệu cần một số cơ sở dữ liệu 'mát xa'. Cơ sở dữ liệu nguồn là một cơ sở dữ liệu MS Access và bảng hiện tại mà tôi đang mắc kẹt là một với một trường đối tượng OLE. Cơ sở dữ liệu đích là cơ sở dữ liệu MS SQL Server Express.NHibernate OutOfMemoryException truy vấn byte lớn []
Trong đơn vị tôi chỉ đơn giản có lĩnh vực này được định nghĩa là một byte[]
Tuy nhiên khi tải tuy nhiên ngay cả khi chỉ tải mà lĩnh vực duy nhất cho một hồ sơ duy nhất tôi đã chạm System.OutOfMemoryException
byte[] test = aSession.Query<Entities.Access.Revision>().Where(x => x.Id == 5590).Select(x => x.FileData).SingleOrDefault<byte[]>();
sau đó tôi đã cố gắng thực hiện blob type listed here nhưng bây giờ khi chạy mà tôi nhận được một lỗi của:
"Unable to cast đối tượng của loại 'System.Byte []' gõ 'TestProg.DatabaseConverter.Entities.Blob'."}
Tôi không thể tưởng tượng được đối tượng Ole lớn hơn 100MB nhưng chưa thể kiểm tra. Có cách nào tốt bằng cách sử dụng Fluent NHibernate để sao chép này ra khỏi cơ sở dữ liệu một và lưu nó vào khác hoặc tôi sẽ cần phải xem xét các tùy chọn khác?
vòng bình thường của tôi để xử lý này là:
IList<Entities.Access.Revision> result;
IList<int> recordIds = aSession.Query<Entities.Access.Revision>().Select(x => x.Id).ToList<int>();
foreach (int recordId in recordIds)
{
result = aSession.Query<Entities.Access.Revision>().Where(x => x.Id == recordId).ToList<Entities.Access.Revision>();
Save(sqlDb, result);
}
Chức năng tiết kiệm chỉ là bản sao đặc tính từ một đến khác và đối với một số đơn vị được sử dụng để thao tác dữ liệu hoặc đưa ra phản hồi cho người sử dụng liên quan đến các vấn đề dữ liệu. Tôi đang sử dụng phiên không trạng thái cho cả hai cơ sở dữ liệu.
-
Từ các thử nghiệm tiếp theo, vật thể dường như đang treo trên khoảng 60-70mb. Tôi hiện đang thử nghiệm lấy dữ liệu với một OleDbDataReader bằng cách sử dụng GetBytes.
-
Cập nhật (ngày 24 tháng 11): Tôi chưa tìm cách để làm việc này với NHibernate. Tôi đã làm việc này với các đối tượng lệnh db thông thường. Tôi đã đặt mã cho chức năng tôi đã thực hiện dưới đây cho bất kỳ ai tò mò tìm thấy điều này. Đây là mã từ trình chuyển đổi cơ sở dữ liệu của tôi để các đối tượng có tiền tố là 'a' là các đối tượng cơ sở dữ liệu truy cập và 's' là các đối tượng sql.
public void MigrateBinaryField(int id, string tableName, string fieldName)
{
var aCmd = new OleDbCommand(String.Format(@"SELECT ID, {0} FROM {1} WHERE ID = {2}", fieldName, tableName, id), aConn);
using (var reader = aCmd.ExecuteReader(System.Data.CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
if (reader[fieldName] == DBNull.Value)
return;
long read = 0;
long offset = 0;
// Can't .WRITE a NULL column so need to set an initial value
var sCmd = new SqlCommand(string.Format(@"UPDATE {0} SET {1} = @data WHERE OldId = @OldId", tableName, fieldName), sConn);
sCmd.Parameters.AddWithValue("@data", new byte[0]);
sCmd.Parameters.AddWithValue("@OldId", id);
sCmd.ExecuteNonQuery();
// Incrementally store binary field to avoid OutOfMemoryException from having entire field loaded in memory
sCmd = new SqlCommand(string.Format(@"UPDATE {0} SET {1}.WRITE(@data, @offset, @len) WHERE OldId = @OldId", tableName, fieldName), sConn);
while ((read = reader.GetBytes(reader.GetOrdinal(fieldName), offset, buffer, 0, buffer.Length)) > 0)
{
sCmd.Parameters.Clear();
sCmd.Parameters.AddWithValue("@data", buffer);
sCmd.Parameters.AddWithValue("@offset", offset);
sCmd.Parameters.AddWithValue("@len", read);
sCmd.Parameters.AddWithValue("@OldId", id);
sCmd.ExecuteNonQuery();
offset += read;
}
}
}
}
Heve bạn đã thử điều này? https://github.com/bittercoder/Lob – Najera
@Najera Tôi đã chụp ảnh đó và không hoạt động. Tôi không thể nhớ các chi tiết cụ thể nhưng dường như nhớ lại vẫn thoát khỏi các ngoại lệ bộ nhớ. Nó đã được một chút trong khi bây giờ mặc dù vậy không phải 100% trên đó. –
Bạn có thể cung cấp cho chúng tôi bản đồ bạn đã thực hiện không? – TedOnTheNet