2
votes

I am using Fluent NHibernate 1.2 for NHibernate 3.1. I have a class:

public class Marks
{
    public virtual int Id { get; set; }
    public virtual IList<string> Answers { get; set; }
}

In the mapping for the Marks class, I have:

HasMany(m => m.Answers).Element("Value");

When the tables are created, an "Answers" table get created with the following columns:

Marks_id (FK, int, not null)
Value (nvarchar(255), null)

What I would like to do is have the Value be nvarchar(max). I'd prefer not doing this for every string in every class, just for this one class.

I have looked at these posts: first, second, third, but haven't found anything yet that helps.

Thanks in advance for any help you can offer. If you need additional information, please let me know.

Edit: This is the code that resolves the issue:

HasMany(x => x.Answers).Element("Value", x => x.Columns.Single().Length = 4001);
3

3 Answers

3
votes

You can force mapping string to longer column at each column level in mapping either by using CustomSqlType("nvarchar(max)") or, bit more universally, by setting Length(4001) (SQL Server magic number, above which it creates nvarchar(max) automatically).

To apply it automatically for all string columns in your entities, you can write your own FluentNHibernate convention:

public class LongStringConvention : IPropertyConvention, IPropertyConventionAcceptance
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Type == typeof(string));
    }

    public void Apply(IPropertyInstance instance)
    {
        instance.Length(4001);
    }
}

And register it in mapping container i.e. like that:

Fluently.Configure()
    .Mappings(...)
    .Conventions.Add<LongStringConvention>()

To apply it for collection of strings, you can use custom element mappings:

HasMany(x => x.Answers).Element("Value", x => x.Columns.Single().Length = 4001);
0
votes

Came across this issue myself and the above answers were most helpful in pointing me in the right direction...but I'm using a slightly newer version of FluentNH.

For Fluent NHibernate 1.3 and NH 3.3.1, the correct code is:

HasMany(x => x.Answers).Element("Value", x => x.Length(4001));
0
votes

The answers above only work for older version of nhibernate. If you try HasMany(x => x.Answers).Element("Value", x => x.Length(4001)); you will get the following:

Error Property or indexer 'FluentNHibernate.MappingModel.ColumnMapping.Length' cannot be assigned to -- it is read only

The correct way to do this now is (NHibernate 4.0.2.4, FluentNHibernate 2.0.1.0):

HasMany(m => m.Answers).Element("Value", e => e.Length(4001))