EF Code First迁移maxLength设置为4000而不是max

时间:2015-08-27 13:02:22

标签: entity-framework ef-code-first ef-migrations

tl; dr:我的列应该是NVARCHAR(MAX)但是使用Add-Migration进行迁移的脚手架会在Up()中为我提供一个最大长度为4000的列。我需要做些什么才能将其变为MAX

考虑以下模型:

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

    [Required]
    [StringLength(100)]
    public string Name { get; set; }

    [Required]
    [DataType(DataType.MultilineText)]
    public string Memo { get; set; }

    [Required]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }
}

我在Context.OnModelCreating中设置了两个约定:

  • 一种约定,它将任何未配置为1024的字符串属性的默认maxLength设置为1024,其中包含以下行:

    Properties<string>().Configure(c => c.HasMaxLength(1024));
    
  • 基于属性的约定,它读取DataTypeAttribute并相应地设置一些属性,即列类型和长度:

        switch (attribute.DataType)
        {
            case DataType.MultilineText:
                configuration.HasColumnType("nvarchar").IsMaxLength();
                break;
            case DataType.EmailAddress:
                configuration.HasColumnType("nvarchar").HasMaxLength(255);
                break;
        }
    

我在设置迁移之前测试了这一切,并且它工作得很漂亮,给了我下面的表格 - 请注意,Memo正在创建为 NVARCHAR(MAX)

CREATE TABLE dbo.Foo (
    Id INT IDENTITY NOT NULL,
    Name NVARCHAR(100) NOT NULL,
    Memo NVARCHAR(MAX) NOT NULL,
    Email NVARCHAR(255) NOT NULL,
    CONSTRAINT [PK_Foo] PRIMARY KEY (Id)
)

然后我启用了迁移并添加了一个,并在Up()中获得了以下表定义:

CreateTable(
    "dbo.Foo",
    c => new
        {
            Id = c.Int(nullable: false, identity: true),
            Name = c.String(nullable: false, maxLength: 100),
            Memo = c.String(nullable: false, maxLength: 4000),
            Email = c.String(nullable: false, maxLength: 255),
        })
    .PrimaryKey(t => t.Id)

什? maxLength: 4000 来自哪里?这不是我期望的MAX,也不是我在第一次约定时将1024配置为默认值。它肯定尊重100255 NameEmail(证明我的基于属性的约定有效)......

那么,这是一个框架中的错误,还是有一些我不理解的迁移?无论哪种方式,我可以做些什么来使Code First Migrations尊重我的IsMaxLength()

1 个答案:

答案 0 :(得分:4)

显然,IsMaxLength() 在上下文与迁移中具有不同的含义。在上下文中,它会创建一个NVARCHAR(MAX)列,但是一旦启用迁移,这将被解释为“列允许的最大可能值,MAX除外”。正如@marc_s在评论中指出的那样,nvarchar列为4000。

事实上,虽然我在移植之外阅读此内容,但设置HasMaxLength(int.MaxValue)并调用Add-Migration会给我以下错误:

  

(0,0):错误0026:MaxLength'2147483647'无效。 'nvarchar'类型的长度必须介于'1'和'4000'之间。

多玩一点,我决定尝试HasColumnType("nvarchar(MAX)"),这让我惊讶工作!因此,替换上述约定中的调用有效。

我找不到任何方法可以在任何可以设置类型的地方读出IsMaxLength()的结果(例如IStoreModelConvention为时已晚),所以这不是最漂亮的解决方案,而是在至少我可以前进。