Naz
Naz

Reputation: 5144

EF Code First 4.1 doesn't support nvarchar(max) at all?

I've spent decent amount of time on this problem and still can't figure out why EF team makes the life so hard using Code First.

So here is some sample:

My POCO:

The way I want the thing to look like:

public class Post
{
     public int Id {get; set;}
     public string Text {get; set;}
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Post>()
        .Property(p => p.Text)
        .HasColumnType("nvarchar(max)");   
}

The only thing that works:

public class Post
{
     public int Id {get; set;}

     [StringLength(4000)]
     public string Text {get; set;}
}

The problem is that when in first case I try to insert anything it gives me: Validation failed for one or more entities and the second case doesn't fit my business model.

Am I the only one with this problem? How do I deal with this thing?

Upvotes: 22

Views: 14550

Answers (5)

Andre Artus
Andre Artus

Reputation: 1890

Using Int32.MaxValue may lead to some problems when connected to a SQL Server database. Using Int32.MaxValue in either the attribute or the api throws an exception stating "String column with MaxLength greater than 4000 is not supported". But, using either of the following methods works fine for me in EF 4.1:

You can use the MaxLengthArritbute, e.g.

[MaxLength]
public string Text { get; set; }

Or the fluent API, like so

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
 {
      modelBuilder.Entity<Post>()
        .Property(s => s.Text)
        .IsMaxLength();
 }

To enforce the use of ntext use one of the following:

[MaxLength]
[Column(TypeName = "ntext")]
public string Text { get; set; }

Or the fluent API, like so

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
 {
      modelBuilder.Entity<Post>()
        .Property(s => s.Text)
        .HasColumnType("ntext") 
        .IsMaxLength();
 }

You may not need the MaxLength attribute in this case.

UPDATE (2017-Sep-6):

As Sebazzz pointed out in his comment ntext (and text) has been deprecated in SQL Server 2016. Here is a link to further information:

https://learn.microsoft.com/en-us/sql/database-engine/deprecated-database-engine-features-in-sql-server-2016

Upvotes: 39

lucas teles
lucas teles

Reputation: 720

I resolved my problem with something like this:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<Post>()
        .Property(p => p.Text)
        .IsMaxLength()
        .HasColumnType("nvarchar(max)");
}

Upvotes: 0

Diganta Kumar
Diganta Kumar

Reputation: 3681

I used the code below to get nvarchar(max) for a field in database. I am using EF5.

using System.Data.Entity.ModelConfiguration;
using Lansw.Panels.Domain.Entities;

    namespace Lansw.Panels.DataAccess.Configurations
    {
        internal class ServiceAgreementConfiguration : EntityTypeConfiguration<ServiceAgreement>
        {
            public ServiceAgreementConfiguration()
            {
                Property(t => t.ServiceAgreementText).IsRequired().IsMaxLength();
            }
        }
    }

enter image description here

Upvotes: 0

Matt Johnson-Pint
Matt Johnson-Pint

Reputation: 241420

Using the [MaxLength] attribute without any value, as described in Andre Artus's post, works perfectly. Under SQL CE it correctly uses "ntext", while under SQL Server it uses "nvarchar(max)". This is highly desired, but should be made clearer in the documentation.

Upvotes: 4

Ladislav Mrnka
Ladislav Mrnka

Reputation: 364249

Use this:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<Post>()
        .Property(p => p.Text)
        .HasMaxLength(Int32.MaxValue);
}

Or this:

[StringLength(Int32.MaxValue)]
public string Text { get; set; }

Upvotes: 4

Related Questions