2009-07-08 15 views
14

Come posso ottenere un Nibernato fluente per creare un campo varbinary in una tabella di SQL Server 2005 che utilizza una dimensione di campo di varbinary (max)? Al momento ottengo sempre un valore predefinito di varbinary (8000), che non è abbastanza grande poiché sto per memorizzare i file di immagine.Come faccio a diventare fluente Nibernate per creare un campo varbinary (max) in sql server

Ho provato a utilizzare CAstle.ActiveRecord ma non ha ancora avuto alcun successo.

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

Conosci non riuscendo a trovare una soluzione per ore, in modo che grazie in anticipo

CZK

risposta

10

non so il motivo per cui il vostro esempio ActiveRecord non funziona, ma ci si potrebbe provare a impostare la lunghezza della colonna.

Con Fluent NHibernate, si dovrebbe essere in grado di fare

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

Prima di tutto, (fastidiosamente) messo il file di mappa nel progetto di base piuttosto che il progetto di dati.

io ancora non sono riuscito a farlo funzionare con un file di mappa, ma ho scritto un file XML, invece, scrivendo la lunghezza del file in - grazie per questo Dan

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

Per quanto ne sappia, non v'è nulla di simile in Fluent NHibernate come "max", tuttavia, se si imposta la lunghezza consentita di una colonna su un valore reale elevato, dovrebbe funzionare correttamente. È possibile controllare MSDN per quale numero max significa per ogni tipo di dati in SQL Server, anche se potrebbe significare un numero molto diverso in altri.

Ho usato riflettore e abbiamo trovato questo:

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

Così, sembra che NHibernate genera max di default? Tuttavia, Fluent no. (Anche se non so perché.)

Con la funzione di mappatura automatica, è possibile utilizzare le convenzioni per raggiungerlo.

Esempio:

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

Per me, questo è sufficiente, ma è sempre possibile utilizzare i numeri più grandi.

Se non si utilizza la mappatura automatica, la soluzione di Dan Fitch è la strada da percorrere, credo.

1

Nell'uso mappatura:

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

4

ho avuto un problema simile con SQL FileStream e Fluent NHibernate dove i miei scritture BLOB sono stati troncando a 8000 byte.La seguente sintassi finalmente risolto il problema:

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

'int.MaxValue' potrebbe essere un modo più piacevole di esprimere il numero magico. Come in '.Length (int.MaxValue)' –

2

È necessario un override di auto-mappatura:

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

Dal momento che si sta utilizzando Castello, si può dire che a cablare NHibernate con le mappature a vostra 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(); 
} 
Problemi correlati