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

发布于 2024-07-26 15:53:42 字数 619 浏览 2 评论 0原文

如何让 nhibernate 流畅地在 sql server 2005 表中创建使用 varbinary(max) 字段大小的 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; }   
}

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

czk

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.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

極樂鬼 2024-08-02 15:53:42

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

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

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

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

With Fluent NHibernate, you should be able to do

Map(x => x.FileData)
    .WithLengthOf(2147483647)
夜雨飘雪 2024-08-02 15:53:42

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

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

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:

Map(x => x.Bytes)
  .CustomSqlType("VARBINARY (MAX) FILESTREAM")
  .Length(2147483647)
  .Not.Nullable();
是伱的 2024-08-02 15:53:42

在映射中使用:

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

In the mapping use:

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

烟─花易冷 2024-08-02 15:53:42

您需要自动映射覆盖:

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

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:

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();
}
幸福不弃 2024-08-02 15:53:42

AFAIK,Fluent NHibernate 中没有“max”这样的东西,但是,如果将列的允许长度设置为真正的大值,它应该可以正常工作。 您可以检查 MSDN,了解 SQL Server 中每种数据类型的 max 数字的含义,尽管在其他数据类型中它可能表示一些非常不同的数字。

我使用 Reflector 并发现了这个:

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 的解决方案是可行的方法。

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.

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.)

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.

谁把谁当真 2024-08-02 15:53:42

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

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

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

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

 <property name="FileName"/>
 <property name="FileType"/>
 <property name="VersionNo"/>
 <property name="FileLength"/>
 <property name="FileData" length="2147483647"/>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文