EF Code First 4.1 не поддерживает nvarchar (max) вообще?

Я потратил приличное количество времени на эту проблему и до сих пор не могу понять, почему команда EF делает жизнь настолько сложной, используя Code First.

Итак, вот несколько примеров:

Мой POCO:

Как я хочу выглядеть так:

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)");   
}

Единственное, что работает:

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

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

Проблема в том, что когда в первом случае я пытаюсь вставить что-нибудь, что мне это дает: Validation failed for one or more entities, а второй случай не подходит для моей бизнес-модели.

Неужели я единственный с этой проблемой? Как я могу справиться с этим?

Ответ 1

Использование Int32.MaxValue может привести к некоторым проблемам при подключении к базе данных SQL Server. Используя Int32.MaxValue в атрибуте или api выдает исключение, в котором указано, что столбец String с MaxLength больше 4000 не поддерживается. Но, используя любой из следующих методов, отлично работает для меня в EF 4.1:

Вы можете использовать MaxLengthArritbute, например

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

Или свободный API, например,

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

Для обеспечения использования ntext используйте одно из следующих действий:

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

Или свободный API, например,

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

В этом случае вам может не понадобиться атрибут MaxLength.

ОБНОВЛЕНИЕ (2017-сент.-6):

Как отметил Sebazzz в своем комментарии ntexttext), он устарел в SQL Server 2016. Ниже приведена ссылка на дополнительную информацию:

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

Ответ 2

Используйте это:

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

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

Или это:

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

Ответ 3

Использование атрибута [MaxLength] без какого-либо значения, как описано в статье Andre Artus, отлично работает. В SQL CE он правильно использует "ntext", тогда как под SQL Server он использует "nvarchar (max)". Это очень желательно, но должно быть уточнено в документации.

Ответ 4

Я использовал код ниже, чтобы получить nvarchar (max) для поля в базе данных. Я использую 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

Ответ 5

Я решил проблему с чем-то вроде этого:

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

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