I also experienced this problem, however with data around 20Mb but also mapped as BinaryBlob (nHibernate v1.2.0) and varbinary(max) on SQL Server 2005.
The workaround for me was to create an IUserType where the code basically is the implementation I found for BinaryBlob and its super classes. With this implementation I've tried with data up 100Mb, around this level I get DB timeout problems but no out of memory exceptions.
Here the code for the IUserType:
Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using NHibernate;
using NHibernate.SqlTypes;
using NHibernate.Util;
namespace Elements.DataPersistanceManager
{
public class UserBlob : NHibernate.UserTypes.IUserType
{
public UserBlob()
{
}
private BinarySqlType sqlType = new BinarySqlType(2147483647);
#region IUserType Members
public object Assemble(object cached, object owner)
{
if (cached == null)
{
return null;
}
else
{
return DeepCopy(cached);
}
}
public object DeepCopy(object value)
{
return (value == null) ? null : DeepCopyNotNull(value);
}
private object DeepCopyNotNull(Object value)
{
byte[] bytes = (byte[])value;
byte[] result = new byte[bytes.Length];
Array.Copy(bytes, 0, result, 0, bytes.Length);
return result;
}
public object Disassemble(object value)
{
if (value == null)
{
return null;
}
else
{
return DeepCopy(value);
}
}
public int GetHashCode(object x)
{
unchecked
{
byte[] bytes = (byte[])x;
int hashCode = 1;
for (int j = 0; j < bytes.Length; j++)
{
hashCode = 31 * hashCode + bytes[j];
}
return hashCode;
}
}
public bool IsMutable
{
get { return true; }
}
public object NullSafeGet(System.Data.IDataReader rs, string[] names, object owner)
{
int index = rs.GetOrdinal(names[0]);
int length = (int)rs.GetBytes(index, 0, null, 0, 0);
byte[] buffer = new byte[length];
int offset = 0;
while (length - offset > 0)
{
int countRead = (int)rs.GetBytes(index, offset, buffer, offset, length - offset);
offset += countRead;
if (countRead == 0)
{
// Should never happen
throw new AssertionFailure("Error in UserBlob.Get, IDataRecord.GetBytes read zero bytes");
}
}
return buffer;
}
public void NullSafeSet(System.Data.IDbCommand cmd, object value, int index)
{
((IDataParameter)cmd.Parameters[index]).Value = (byte[])value;
}
public object Replace(object original, object target, object owner)
{
return DeepCopy(original);
}
public Type ReturnedType
{
get { return typeof(byte[]); }
}
public NHibernate.SqlTypes.SqlType[] SqlTypes
{
get { return new SqlType[] {sqlType}; }
}
public new bool Equals(object x, object y)
{
if (x == y)
{
return true;
}
if (x == null || y == null)
{
return false;
}
return CollectionHelper.CollectionEquals((byte[])x, (byte[])y);
}
#endregion
}
}
and the equivalent mapping (the length affects the type of db type that is generated when I generate a schema according to the mapping. I use sql server 2005 and sql server compact edition. 8001 gives me nvarbinary(max) and image respectively):
Code:
<property name="Buffer" column ="Buffer" type="Elements.DataPersistanceManager.UserBlob, Elements.DataPersistanceManager" access="property" length="8001"/>
hope this help...