user610217
user610217

Reputation:

Set EF6 Code First strings fluently to nvarchar(max)

I'm building an EF6 code first model using the fluent API. My understanding is, by default, strings will be nvarchar(max), which (to be blunt) is dumb for a default. So I added the following convention code to set max default length to 255 characters:

modelBuilder.Properties<string>()
    .Configure(p => p.HasMaxLength(255));

Then I created a decorator like so:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class TextAttribute : Attribute
{
}

I want to apply this to specific string properties that I actually want to be NVARCHAR(MAX).

What do I put in the fluent API to make sure all string properties with the [Text] decorator are built in the database with NVARCHAR(MAX)? I assume it would be something like this:

modelBuilder.Properties<string>()
    .Where(p => p.CustomAttributes.Any(a => typeof(TextAttribute).IsAssignableFrom(a.AttributeType)))
    .Configure(p => p.HasMaxLength(?????));

Or am I doing this completely wrong?

Upvotes: 27

Views: 29356

Answers (6)

TotPeRo
TotPeRo

Reputation: 6781

If you use other database provider than MS SQL Server then column type is possible to be other than NVARCHAR and for this you need to use HasMaxLength combine with IsUnicode.

If you use:

builder.Property(e => e.ColumnName)
        .HasColumnType("nvarchar(max)");

This is hard-coded for MS SQL Server database provider and if you want to switch to other provider in time, you need to change all your entities configuration and also to change the migrations.

For example PostgreSql: PostgreSQL equivalent to SQL Server NVARCHAR (MAX) or Whats SQL Server NVARCHAR(max) equivalent in MySQL?

You can use for NVARCHAR(MAX):

builder.Property(e => e.ColumnName)
    .HasMaxLength(int.MaxValue)
    .IsUnicode(true);

You can use for VARCHAR(MAX):

builder.Property(e => e.ColumnName)
    .HasMaxLength(int.MaxValue)
    .IsUnicode(false);

Upvotes: 3

Mohammad Nikravan
Mohammad Nikravan

Reputation: 1809

It works for me in EF Core 7

entity.Property(e => e.ColumnName)
    .HasMaxLength(int.MaxValue);

Upvotes: 2

Ergin &#199;elik
Ergin &#199;elik

Reputation: 775

You can use HasColumnType

enter image description here

or you can use without any HasColumnType or HasMaxLength. There is no need to use HasMaxLength

enter image description here

Upvotes: 3

Dionny Prensa
Dionny Prensa

Reputation: 139

There is a method to indicate that you use the maximum allowed by the database.

IsMaxLength ()

    modelBuilder.Properties<string>()
        .Where(p => p.CustomAttributes.Any(a => typeof(TextAttribute).IsAssignableFrom(a.AttributeType)))
        .Configure(p => p.HasColumnType("nvarchar").IsMaxLength());

Upvotes: 8

Katie Kilian
Katie Kilian

Reputation: 6985

If you're doing it inside an EntityTypeConfiguration<MyEntity> class, it is similar to @RickNo's answer, but is done like this:

Property(x => x.MyVarcharMaxProperty)
    .HasColumnType("nvarchar(max)");

Upvotes: 18

RickNo
RickNo

Reputation: 423

I don't know if you've found an answer by now, but in case anyone else is wondering how to do it, simply set the SQL datatype and ignore the HasMaxLength() invocation.

        modelBuilder.Properties<string>()
            .Where(p => p.CustomAttributes.Any(a => typeof(TextAttribute).IsAssignableFrom(a.AttributeType)))
            .Configure(p => p.HasColumnType("nvarchar(max)"));

Using IsMaxLength() or HasMaxLength(null) would set the field to nvarchar(4000) (varchar(8000) if specifying the data type as varchar).

Upvotes: 31

Related Questions