【问题标题】:EF Code First 4.1 doesn't support nvarchar(max) at all?EF Code First 4.1 根本不支持 nvarchar(max) 吗?
【发布时间】:2011-07-17 19:09:58
【问题描述】:

我在这个问题上花费了大量时间,但仍然无法弄清楚为什么 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,而第二种情况不适合我的商业模式。

只有我一个人有这个问题吗?我该如何处理这件事?

【问题讨论】:

    标签: entity-framework orm ef-code-first entity-framework-4.1


    【解决方案1】:

    在连接到 SQL Server 数据库时,使用Int32.MaxValue 可能会导致一些问题。在属性或 api 中使用 Int32.MaxValue 会引发异常,指出“不支持 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 年 9 月 6 日):

    正如 Sebazzz 在他的评论中指出的那样,ntext(和 text)在 SQL Server 2016 中已被弃用。这里是更多信息的链接:

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

    【讨论】:

    • 请注意 ntext 已弃用。不建议将其用于新开发。
    【解决方案2】:

    我用这样的方法解决了我的问题:

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

    【讨论】:

      【解决方案3】:

      我使用下面的代码为数据库中的一个字段获取 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();
                  }
              }
          }
      

      【讨论】:

        【解决方案4】:

        如 Andre Artus 的帖子中所述,使用不带任何值的 [MaxLength] 属性非常有效。在 SQL CE 下它正确使用“ntext”,而在 SQL Server 下它使用“nvarchar(max)”。这是非常需要的,但应该在文档中更清楚地说明。

        【讨论】:

        • 如果你想强制ntext,那么很容易申请[Column(TypeName = "ntext")].HasColumnType("ntext"),就像我在最初的帖子中所做的那样。
        • 仅供参考 - 这在最终的 EF4.1 版本中已更改。它默认使用 nvarchar(max) 而不使用 [MaxLength] 属性。这是应该的。 :)
        • 很高兴知道这一点。看来我得重新研究一下 EF 4.1。
        • SQL CE 4 + EF 4.1 它使用 nvarchar(4000) 而不是 ntext
        【解决方案5】:

        使用这个:

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

        【讨论】:

        • EF 团队应该为 Code First 列出“黑客”列表 :)
        • @NazarGargol:当它发布时,他们会推出一个。但他们会称其为“官方文档”
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多