12

using fluent nhibernate, and automappings (nhibernate creates my db schema), how can i get nhibernate to create a nvarchar(max) column in the database based on the following class

public class VirtualPage : BaseEntity
{
    public virtual int ParentId { get; set; }
    public virtual string PageName { get; set; }
    public virtual string Title { get; set; }
    public virtual string Body { get; set; }
    public virtual string ViewName { get; set; }
    public virtual string ViewData { get; set; } // this must be nvarchar(max)
}
stoic
  • 4,700
  • 13
  • 58
  • 88

3 Answers3

32

With automapping you can override the default length for text fields, but it will be applied to all text fields.

You should be able to combine automapping with explicit mappings created with the fluent API.

Fortunately, this is a pretty simple class to map (I'm assuming that this is part of a table-per-subclass hierarchy, which is why I use SubClassMap<> instead of ClassMap<> and do not map an identifier):

public class VirtualPageMap : SubClassMap<VirtualPage>
{
    public VirtualPageMap()
    {
        Map(x => x.ParentId);
        Map(x => x.PageName);
        Map(x => x.Title);
        Map(x => x.Body);
        Map(x => x.ViewName);
        Map(x => x.ViewData).Length(4001); // anything over 4000 is nvarchar(max)
    }
}

I've actually never used automappings, so I'm assuming that this will be picked up properly, but do not know for sure.

Don't forget to add the mapping in your configuration.

Fluently.configure(
    // blah blah blah
    .Mappings(m => 
    {
        m.FluentMappings.AddFromAssemblyOf<VirtualPage>();
        m.AutoMappings.Add( // blah blah blah
    }
Jay
  • 56,361
  • 10
  • 99
  • 123
  • thanx m8, after little configuration and using your example it worked like a charm.. – stoic Aug 27 '10 at 20:04
  • Please keep in mind that using .Length(int.MaxValue) maps to nvarchar (255). Also, not using .Length at all, maps to nvarchar (255) – veeroo Mar 27 '17 at 13:31
2

Set the Length property to a high number (I use 10000) - this will cause NHibernate to make a nvarchar(max)

Goblin
  • 7,970
  • 3
  • 36
  • 40
  • how does one set the length of a property? – stoic Aug 20 '10 at 15:32
  • Map(x => x.).Length(10000) :-) – Goblin Aug 20 '10 at 15:41
  • hmmmm sorry... maybe i should have told you that i started using nhibernate 2 days ago :), this means i have absolutely NO idea where that must go. thanx for helping though – stoic Aug 20 '10 at 15:44
  • Ahh - I missed the AutoMapping part, sorry about that. See this blogpost for how to achieve it for a single property: http://serialseb.blogspot.com/2009/01/fluent-nhibernate-and-nvarcharmax.html – Goblin Aug 20 '10 at 16:41
0

As an alternative if you prefer to work with attributes directly on your domain rather than having all the lengths within the mappings you can do as follows

In your domain use the built in StringLength attribute, for nvarchar(max) set it to 4001 or higher

[StringLength(4001)]
public virtual string? Description { get; set; }

Then you can create a property convention to map this

public class StringLengthConvention : AttributePropertyConvention<StringLengthAttribute>
{
   protected override void Apply(StringLengthAttribute attribute, IPropertyInstance instance)
   {
       instance.Length(attribute.MaximumLength);
   }
}

Which can then be added to your mappings something like this

  .Mappings(m =>
            m.AutoMappings
                .Add(AutoMap.AssemblyOf<Show>(automappingConfiguration).Conventions.Setup(
                    c =>
                    {
                        c.Add<PrimaryKeyConvention>();
                        c.Add<CustomForeignKeyConvention>();
                        c.Add<StringLengthConvention>();
                    }
                    )))
dove
  • 20,469
  • 14
  • 82
  • 108