如何让fluent nhibernate在sql server中创建varbinary(max)字段

时间:2022-06-16 00:55:35

How can I get fluent nhibernate to create a varbinary field in a sql server 2005 table that uses a field size of varbinary(max)? At the moment I always get a default of varbinary(8000), which isn't big enough as i'm going to be storing image files.

如何让fluent nhibernate在使用varbinary(max)字段的sql server 2005表中创建varbinary字段?目前,我总是得到一个默认的varbinary(8000),这个值不够大,因为我要存储图像文件。

I've tried using CAstle.ActiveRecord but havent had any success yet.

我试着使用城堡。但是还没有成功。

 [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; }   
}

Been failing at finding a solution for hours now, so thanks in advance

我已经好几个小时没有找到解决方案了,所以先谢谢你

czk

czk

6 个解决方案

#1


10  

I'm not sure why your ActiveRecord example is not working, but there you might try setting the length of the column.

我不确定为什么ActiveRecord示例不能工作,但是您可以尝试设置列的长度。

With Fluent NHibernate, you should be able to do

使用流畅的NHibernate,您应该能够做到。

Map(x => x.FileData)
    .WithLengthOf(2147483647)

#2


4  

I was having a similar issue with SQL FileStream and Fluent NHibernate where my BLOB writes were truncating at 8000 bytes. The following syntax finally fixed the problem:

我也遇到过类似的问题,比如SQL文件流和Fluent NHibernate,我的BLOB写入在8000字节处截断。下面的语法最终解决了这个问题:

Map(x => x.Bytes)
  .CustomSqlType("VARBINARY (MAX) FILESTREAM")
  .Length(2147483647)
  .Not.Nullable();

#3


2  

You need an auto-mapping override:

您需要一个自动映射覆盖:

public class MyFileMapOverride : IAutoMappingOverride<MyFile>
{
    public void Override( AutoMapping<MyFile> mapping )
    {
        mapping.Map( x => x.FileData ).Length( int.MaxValue );
    }
}

Since you're using Castle, you can tell it to wire up NHibernate with your mappings in your NHibernateInstaller:

因为您正在使用Castle,所以可以告诉它在NHibernateInstaller中使用映射来连接NHibernate:

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();
}

#4


1  

AFAIK, there is no such thing in Fluent NHibernate as "max", however, if you set the allowed length of a column to a real big value, it should work fine. You can check MSDN for what number max means for each datatype in SQL Server, although it may mean some very different number in others.

AFAIK,在流畅的NHibernate中没有“max”这样的东西,但是,如果您将允许的列长度设置为一个真正的大值,那么它应该可以正常工作。您可以检查MSDN,看看SQL Server中每个数据类型的数字max是什么意思,尽管它在其他数据类型中可能意味着非常不同的数字。

I used reflector and found this:

我用反射器找到了这个:

public MsSql2005Dialect()
{
    base.RegisterColumnType(DbType.String, 0x3fffffff, "NVARCHAR(MAX)");
    base.RegisterColumnType(DbType.AnsiString, 0x7fffffff, "VARCHAR(MAX)");
    base.RegisterColumnType(DbType.Binary, 0x7fffffff, "VARBINARY(MAX)");
}

So, it seems that NHibernate creates max by default? Still, Fluent doesn't. (Although I don't know why.)

那么,NHibernate在默认情况下创建了max ?不过,流利的不喜欢。(虽然我不知道为什么。)

With the Auto mapping feature, you can use conventions to achieve it.

使用自动映射特性,您可以使用约定来实现它。

Example:

例子:

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();

For me, this suffices, but you can always use larger numbers.

对我来说,这就足够了,但是你可以用更大的数字。

If you don't use automapping, Dan Fitch's solution is the way to go, I guess.

如果你不使用自动机,Dan Fitch的解决方案是可行的,我猜。

#5


1  

In the mapping use:

在映射使用:

Map(x => x.FileData).CustomSqlType("VARBINARY(MAX)");

地图(x = > x.FileData).CustomSqlType(“VARBINARY(MAX)");

#6


0  

First off, I (annoyingly) put the map file into the core project rather than the data project.

首先,我(令人恼火地)将映射文件放在核心项目中,而不是数据项目中。

I still couldn't get it to work with a map file, but i wrote an xml file instead, writing the file length in - thanks for that Dan

我仍然无法让它与映射文件一起工作,但是我编写了一个xml文件,将文件长度写入—感谢Dan

 <property name="FileName"/>
 <property name="FileType"/>
 <property name="VersionNo"/>
 <property name="FileLength"/>
 <property name="FileData" length="2147483647"/>

#1


10  

I'm not sure why your ActiveRecord example is not working, but there you might try setting the length of the column.

我不确定为什么ActiveRecord示例不能工作,但是您可以尝试设置列的长度。

With Fluent NHibernate, you should be able to do

使用流畅的NHibernate,您应该能够做到。

Map(x => x.FileData)
    .WithLengthOf(2147483647)

#2


4  

I was having a similar issue with SQL FileStream and Fluent NHibernate where my BLOB writes were truncating at 8000 bytes. The following syntax finally fixed the problem:

我也遇到过类似的问题,比如SQL文件流和Fluent NHibernate,我的BLOB写入在8000字节处截断。下面的语法最终解决了这个问题:

Map(x => x.Bytes)
  .CustomSqlType("VARBINARY (MAX) FILESTREAM")
  .Length(2147483647)
  .Not.Nullable();

#3


2  

You need an auto-mapping override:

您需要一个自动映射覆盖:

public class MyFileMapOverride : IAutoMappingOverride<MyFile>
{
    public void Override( AutoMapping<MyFile> mapping )
    {
        mapping.Map( x => x.FileData ).Length( int.MaxValue );
    }
}

Since you're using Castle, you can tell it to wire up NHibernate with your mappings in your NHibernateInstaller:

因为您正在使用Castle,所以可以告诉它在NHibernateInstaller中使用映射来连接NHibernate:

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();
}

#4


1  

AFAIK, there is no such thing in Fluent NHibernate as "max", however, if you set the allowed length of a column to a real big value, it should work fine. You can check MSDN for what number max means for each datatype in SQL Server, although it may mean some very different number in others.

AFAIK,在流畅的NHibernate中没有“max”这样的东西,但是,如果您将允许的列长度设置为一个真正的大值,那么它应该可以正常工作。您可以检查MSDN,看看SQL Server中每个数据类型的数字max是什么意思,尽管它在其他数据类型中可能意味着非常不同的数字。

I used reflector and found this:

我用反射器找到了这个:

public MsSql2005Dialect()
{
    base.RegisterColumnType(DbType.String, 0x3fffffff, "NVARCHAR(MAX)");
    base.RegisterColumnType(DbType.AnsiString, 0x7fffffff, "VARCHAR(MAX)");
    base.RegisterColumnType(DbType.Binary, 0x7fffffff, "VARBINARY(MAX)");
}

So, it seems that NHibernate creates max by default? Still, Fluent doesn't. (Although I don't know why.)

那么,NHibernate在默认情况下创建了max ?不过,流利的不喜欢。(虽然我不知道为什么。)

With the Auto mapping feature, you can use conventions to achieve it.

使用自动映射特性,您可以使用约定来实现它。

Example:

例子:

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();

For me, this suffices, but you can always use larger numbers.

对我来说,这就足够了,但是你可以用更大的数字。

If you don't use automapping, Dan Fitch's solution is the way to go, I guess.

如果你不使用自动机,Dan Fitch的解决方案是可行的,我猜。

#5


1  

In the mapping use:

在映射使用:

Map(x => x.FileData).CustomSqlType("VARBINARY(MAX)");

地图(x = > x.FileData).CustomSqlType(“VARBINARY(MAX)");

#6


0  

First off, I (annoyingly) put the map file into the core project rather than the data project.

首先,我(令人恼火地)将映射文件放在核心项目中,而不是数据项目中。

I still couldn't get it to work with a map file, but i wrote an xml file instead, writing the file length in - thanks for that Dan

我仍然无法让它与映射文件一起工作,但是我编写了一个xml文件,将文件长度写入—感谢Dan

 <property name="FileName"/>
 <property name="FileType"/>
 <property name="VersionNo"/>
 <property name="FileLength"/>
 <property name="FileData" length="2147483647"/>