2009-07-08 12 views
14

¿Cómo puedo obtener nhibernate con fluidez para crear un campo varbinary en una tabla sql server 2005 que usa un tamaño de campo de varbinary (max)? Por el momento siempre obtengo un valor predeterminado de varbinary (8000), que no es lo suficientemente grande ya que voy a almacenar archivos de imágenes.¿Cómo obtengo nhibernate fluido para crear un campo varbinary (max) en el servidor sql

He intentado usar CAstle.ActiveRecord pero todavía no he tenido éxito.

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

estado fallando en encontrar una solución durante horas, así que gracias de antemano

czk

Respuesta

10

no estoy seguro de por qué su ejemplo ActiveRecord no está funcionando, pero no es posible que intente ajustar el longitud de la columna.

Con Fluido NHibernate, usted debe ser capaz de hacer

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

En primer lugar, yo (molesto) poner el archivo de mapa en el proyecto principal en lugar del proyecto de datos.

todavía no podía conseguir que funcione con un archivo de mapa, pero escribí un archivo XML en su lugar, escribir la longitud del archivo en - gracias por que Dan

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

yo sepa, no hay tal cosa en Fluiber NHibernate como "máximo", sin embargo, si establece la longitud permitida de una columna en un valor real grande, debería funcionar bien. Puede consultar MSDN para saber qué número máximo significa para cada tipo de datos en SQL Server, aunque puede significar un número muy diferente en otros.

que utilizan reflector y encontré esto:

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

Por lo tanto, parece que NHibernate crea máximo por defecto? Aún así, Fluent no lo hace. (Aunque no sé por qué.)

Con la función Auto mapping, puede usar convenciones para lograrlo.

Ejemplo:

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

Para mí, esto es suficiente, pero siempre se puede utilizar un número mayor.

Si no usa la automatización, la solución de Dan Fitch es el camino a seguir, supongo.

1

En el uso de mapas:

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

4

que estaba teniendo un problema similar con SQL FileStream y Fluent NHibernate donde mis escrituras BLOB se truncando a 8000 bytes.La siguiente sintaxis finalmente se solucionó el problema:

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

'int.MaxValue' podría ser una forma más agradable de expresar el número mágico. Como en '.Length (int.MaxValue)' –

2

Es necesario un reemplazo de asignación automática:

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

Dado que está utilizando Castillo, se le puede decir que cablear NHibernate con sus asignaciones en su 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(); 
} 
Cuestiones relacionadas