Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting string to be sql type of "varchar" instead of "nvarchar"

I have the following mapping:

public class LogEntryMap
{
    public LogEntryMap()
    {
        Map.Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.Context).CustomSqlType("varchar").Length(512);
    }
}

However, using SchemaExport to generate the database in SQL Server 2008, the script generated ignores the length so in effect it ends up being a varchar with length of 1:

create table OV_SAC.dbo.[LogEntry] (
    Id BIGINT IDENTITY NOT NULL,
   Context varchar null,
   primary key (Id)
)

.CustomSqlType("varchar 512") throws an exception. And without defining the CustomSqlType, strings are mapped to nvarchar (which does respect the Length property).

Any suggestions?

like image 407
Ted Avatar asked Feb 26 '10 20:02

Ted


People also ask

Should I use VARCHAR or NVARCHAR?

Today's development platforms or their operating systems support the Unicode character set. Therefore, In SQL Server, you should utilize NVARCHAR rather than VARCHAR. If you do use VARCHAR when Unicode support is present, then an encoding inconsistency will arise while communicating with the database.

How do I select a VARCHAR in SQL?

varchar [ ( n | max ) ] Variable-size string data. Use n to define the string size in bytes and can be a value from 1 through 8,000 or use max to indicate a column constraint size up to a maximum storage of 2^31-1 bytes (2 GB).

Is VARCHAR a string?

VARCHAR is a variable length string data type, so it holds only the characters you assign to it. VARCHAR takes up 1 byte per character, + 2 bytes to hold length information.

What is datatype NVARCHAR?

The NVARCHAR data type stores character data in a variable-length field. Data can be a string of single-byte or multibyte letters, digits, and other characters that are supported by the code set of your database locale.


2 Answers

Use .CustomType("AnsiString") instead of default "String" and NHibernate will use varchar instead of nvarchar.

like image 97
Szymon Pobiega Avatar answered Sep 22 '22 20:09

Szymon Pobiega


If you wanted all of your strings to be mapped to varchar instead of nvarchar you could consider using a convention:

/// <summary>
/// Ensures that all of our strings are stored as varchar instead of nvarchar.
/// </summary>
public class OurStringPropertyConvention : IPropertyConvention
{
    public void Apply(IPropertyInstance instance)
    {
        if (instance.Property.PropertyType == typeof (string))
            instance.CustomType("AnsiString");
    }
}

You mappings could then go back to a simple mapping:

Map(x => x.Context);

Just make sure you remember to tell Fluent NH to use the convention:

        var configuration = new Configuration();
        configuration.Configure();
        Fluently
            .Configure(configuration)
            .Mappings(m => m.FluentMappings
                .AddFromAssemblyOf<Widget>()
                .Conventions.Add<OurStringPropertyConvention>()
                )
            .BuildSessionFactory();
like image 45
Jonathan Moffatt Avatar answered Sep 22 '22 20:09

Jonathan Moffatt