Ответ 1
Я не уверен, почему ваш пример ActiveRecord не работает, но вы можете попробовать установить длину столбца.
С Fluent NHibernate вы сможете выполнять
Map(x => x.FileData)
.WithLengthOf(2147483647)
Как я могу свободно говорить nhibernate для создания поля varbinary в таблице sql server 2005, в которой используется размер поля varbinary (max)? На данный момент я всегда получаю дефолт varbinary (8000), который недостаточно велик, поскольку я собираюсь хранить файлы изображений.
Я пытался использовать CAstle.ActiveRecord, но havent еще успел.
[ActiveRecord]
public class MyFile : Entity
{
public virtual string FileName { get; set; }
public virtual string FileType { get; set; }
public virtual int FileVersion { get; set; }
public virtual int FileLength { get; set; }
[Property(ColumnType = "BinaryBlob", SqlType = "VARBINARY(MAX)")]
public virtual byte[] FileData { get; set; }
}
Не удалось найти решение в течение нескольких часов, поэтому заранее спасибо
Кч
Я не уверен, почему ваш пример ActiveRecord не работает, но вы можете попробовать установить длину столбца.
С Fluent NHibernate вы сможете выполнять
Map(x => x.FileData)
.WithLengthOf(2147483647)
У меня была аналогичная проблема с SQL FileStream и Fluent NHibernate, где мои записи BLOB были обрезаны с 8000 байтами. Следующий синтаксис окончательно устранил проблему:
Map(x => x.Bytes)
.CustomSqlType("VARBINARY (MAX) FILESTREAM")
.Length(2147483647)
.Not.Nullable();
Вам необходимо переопределить авто-отображение:
public class MyFileMapOverride : IAutoMappingOverride<MyFile>
{
public void Override( AutoMapping<MyFile> mapping )
{
mapping.Map( x => x.FileData ).Length( int.MaxValue );
}
}
Поскольку вы используете Castle, вы можете сказать ему подключить NHibernate с вашими сопоставлениями в вашем NHibernateInstaller:
public void Install( IWindsorContainer container, IConfigurationStore store )
{
container.Register( Component.For<ISessionFactory>()
.UsingFactoryMethod( k => BuildSessionFactory() )
.Named( "MySessionFactory" ) );
// Do other stuff...
}
private ISessionFactory BuildSessionFactory()
{
var mappings = AutoMap.AssemblyOf<MyFile>()
.IgnoreBase( typeof(Entity) )
.UseOverridesFromAssemblyOf<MyFileMapOverride>();
var configuration = ConfigurationUtility
.CreateConfiguration<WebSessionContext, DefaultProxyFactoryFactory>(
"MyDbConnection",
ConfigurationUtility.ForMsSql,
mappings,
NHibernateConfiguration.GetConfigurationPath() );
return configuration.BuildSessionFactory();
}
AFAIK, нет такой вещи в Fluent NHibernate как "max", однако, если вы установите допустимую длину столбца на реальное большое значение, оно должно работать нормально. Вы можете проверить MSDN, какое число max означает для каждого типа данных в SQL Server, хотя это может означать несколько другое число в других.
Я использовал отражатель и нашел это:
public MsSql2005Dialect()
{
base.RegisterColumnType(DbType.String, 0x3fffffff, "NVARCHAR(MAX)");
base.RegisterColumnType(DbType.AnsiString, 0x7fffffff, "VARCHAR(MAX)");
base.RegisterColumnType(DbType.Binary, 0x7fffffff, "VARBINARY(MAX)");
}
Итак, кажется, что NHibernate создает max по умолчанию? Тем не менее, Fluent этого не делает. (Хотя я не знаю почему.)
С помощью функции автоматического сопоставления вы можете использовать соглашения для ее достижения.
Пример:
var cfg = new Configuration();
var persistenceModel = new AutoPersistenceModel();
persistenceModel.Conventions.Add(
new PropertyConvention(),
new ReferenceConvention(),
new HasManyConvention(),
ConventionBuilder.Property.Always(delegate(IPropertyInstance instance)
{
if (instance.Property.PropertyType == typeof(string))
instance.Length(16000);
else if (instance.Property.PropertyType == typeof(byte[]))
instance.Length(30000000);
}));
persistenceModel.AddTypeSource(new AssemblyTypeSource(Assembly.GetExecutingAssembly()));
persistenceModel.Where(t => t.Namespace.EndsWith("Entities"));
cfg.AddAutoMappings(persistenceModel);
return cfg.BuildSessionFactory();
Для меня это достаточно, но вы всегда можете использовать большие числа.
Если вы не используете автоматизацию, решение Dan Fitch - это путь, я думаю.
В картографии используется:
Map(x => x.FileData).CustomSqlType("VARBINARY(MAX)");
Во-первых, я (досадно) помещает файл карты в основной проект, а не проект данных.
Я все еще не мог заставить его работать с файлом карты, но вместо этого написал xml файл, записав длину файла - спасибо за это Dan
<property name="FileName"/>
<property name="FileType"/>
<property name="VersionNo"/>
<property name="FileLength"/>
<property name="FileData" length="2147483647"/>