2009-07-08 10 views
14

Jak mogę uzyskać płynne nhibernate, aby utworzyć varbinary pole w tabeli SQL Server 2005, który używa pola varbinary (max)? W tej chwili zawsze otrzymuję domyślną wersję varbinary (8000), która nie jest wystarczająco duża, ponieważ zamierzam przechowywać pliki obrazów.Jak uzyskać płynną nhibernate do utworzenia varbinary (max) pola w serwerze sql

Próbowałem już używać CASTle.ActiveRecord, ale jeszcze nie miałem żadnego sukcesu.

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

Byłeś braku na znalezienie rozwiązania dla godzin teraz, więc z góry dzięki

czk

Odpowiedz

10

Nie jestem pewien, dlaczego Twój przykład ActiveRecord nie działa, ale można spróbować ustawienie długość kolumny.

Z Fluent NHibernate, powinieneś być w stanie zrobić

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

pierwsze, I (irytująco) umieścić plik mapy do projektu podstawowego zamiast projektu danych.

ja wciąż nie może zmusić go do pracy z pliku mapy, ale napisałem plik xml zamiast pisać długość pliku w - Dzięki za to Dan

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

AFAIK, nie ma czegoś takiego w Fluent NHibernate jako "max", jednak jeśli ustawisz dozwoloną długość kolumny na naprawdę dużą wartość, powinno to działać poprawnie. Możesz sprawdzić MSDN dla jakiej liczby max oznacza dla każdego typu danych w SQL Server, chociaż może to oznaczać bardzo różne liczby w innych.

użyłem reflektor i stwierdziliśmy:

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

Więc wydaje się, że NHibernate tworzy max domyślnie? Jednak Fluent nie. (Chociaż nie wiem dlaczego.)

Dzięki funkcji automatycznego mapowania można używać konwencji, aby to osiągnąć.

Przykład:

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

Dla mnie to wystarczy, ale zawsze można użyć większych liczb.

Jeśli nie korzystasz z automatyzacji, to rozwiązanie Dan Fitch jest drogą, jak sądzę.

1

W zastosowaniu mapowania:

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

4

Miałem podobny problem z SQL FileStream i Fluent NHibernate gdzie moje zapisy BLOB zostały obcinanie na 8000 bajtów.Poniższa składnia wreszcie naprawili problem:

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

'int.MaxValue' może być ładniejszym sposobem wyrażania magicznej liczby. Jak w '.Length (int.MaxValue)' –

2

Trzeba nadpisanie automatycznego mapowania:

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

Ponieważ używasz Castle, można powiedzieć, że na drut NHibernate z mapowania w twojej 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(); 
} 
Powiązane problemy