14

如何让流利的 nhibernate 在使用 varbinary(max) 字段大小的 sql server 2005 表中创建 varbinary 字段?目前我总是得到一个默认值 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; }   
}

几个小时以来一直未能找到解决方案,所以在此先感谢

捷克克

4

6 回答 6

10

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

使用 Fluent NHibernate,您应该能够做到

Map(x => x.FileData)
    .WithLengthOf(2147483647)
于 2009-07-08T15:33:44.113 回答
5

我在使用 SQL FileStream 和 Fluent NHibernate 时遇到了类似的问题,我的 BLOB 写入在 8000 字节处被截断。下面的语法最终解决了这个问题:

Map(x => x.Bytes)
  .CustomSqlType("VARBINARY (MAX) FILESTREAM")
  .Length(2147483647)
  .Not.Nullable();
于 2012-06-12T21:52:02.553 回答
2

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

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

由于您使用的是 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();
}
于 2014-09-26T17:38:59.867 回答
2

在映射中使用:

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

于 2010-08-14T18:21:23.017 回答
1

AFAIK,Fluent NHibernate 中没有“max”这样的东西,但是,如果您将列的允许长度设置为一个真正的大值,它应该可以正常工作。您可以查看 MSDN 以了解 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 似乎默认创建最大值?不过,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 的解决方案是可行的方法。

于 2010-05-07T12:05:23.653 回答
0

首先,我(恼人地)将地图文件放入核心项目而不是数据项目。

我仍然无法让它与地图文件一起使用,但我写了一个 xml 文件,将文件长度写入 - 感谢 Dan

 <property name="FileName"/>
 <property name="FileType"/>
 <property name="VersionNo"/>
 <property name="FileLength"/>
 <property name="FileData" length="2147483647"/>
于 2009-07-14T16:05:47.730 回答