Как получить свободный nhibernate для создания поля varbinary(max) на сервере SQL
Как я могу свободно использовать nhibernate для создания поля varbinary в таблице sql server 2005, в которой используется размер поля varbinary(max)? В настоящее время я всегда получаю значение по умолчанию varbinary(8000), которое недостаточно для хранения файлов изображений.
Я пытался использовать CAstle.ActiveRecord, но еще не было никакого успеха.
[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; }
}
Уже несколько часов не могу найти решение, так что спасибо заранее
Кч
6 ответов
Я не уверен, почему ваш пример 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();
В картировании используйте:
Map(x => x.FileData).CustomSqlType("VARBINARY(MAX)");
Вам нужно переопределение автоматического сопоставления:
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 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 по умолчанию? Тем не менее, свободно говорит. (Хотя я не знаю почему.)
С помощью функции автоматического сопоставления вы можете использовать соглашения для достижения этой цели.
Пример:
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();
Для меня этого достаточно, но вы всегда можете использовать большие числа.
Я полагаю, что если вы не используете autopping, решение Дана Фитча - это то, что вам нужно.
Прежде всего, я (досадно) поместил файл карты в основной проект, а не в проект данных.
Я все еще не мог заставить его работать с файлом карты, но вместо этого я написал файл XML, записав длину файла - спасибо за это, Дэн
<property name="FileName"/>
<property name="FileType"/>
<property name="VersionNo"/>
<property name="FileLength"/>
<property name="FileData" length="2147483647"/>