【问题标题】:What happens if I don't specify StringLength or MaxLength on a string property?如果我没有在字符串属性上指定 StringLength 或 MaxLength 会发生什么?
【发布时间】:2018-11-04 13:59:15
【问题描述】:

现在我正在使用代码优先的方法为数据库创建模型。这将是一个非常大的数据(如数百万行)。所以,我对我选择的类型非常小心。尽可能使用短裤、字节和枚举。

现在,StringLength 和 MaxLength 注释都在限制字符串(或后者的数组)的最大允许长度。

那么,他们是否指定数据库为该字段保留的字节数?如果是这样,在未指定时保留了多少字节?或者它们仅仅是为了验证目的而仅此而已?

我什至不确定数据库中的保留空间是否与我选择的类型相关。也许里面的逻辑完全不同。

当我想到它时,另一个问题出现在我的脑海中。如果我添加一个带有 StringLength(1000) 的“文章”列,会发生什么?考虑到一个 char 占用 2 个字节,现在是否为每个字段保留 2kB?还是与此完全无关?

【问题讨论】:

  • 这可能取决于您使用的数据库平台。您是否在自己的数据库上亲自尝试过?发生了什么?
  • 对于诸如“如果……会发生什么”或“我能……”之类的问题的答案几乎总是很简单:试一试,看看会发生什么。在这种情况下,我们应该如何知道您的数据库在做什么?
  • 是MS SQL Server 2017。不,我还没有机会尝试,数据库现在是空的。我可能会尝试添加虚拟数据来测试自己,但客户正在等待,我现在必须在这个项目上努力工作:)
  • 我认为这是常识。我对这个数据库的东西很陌生。
  • @EmreCanSerteli 常识并不常见,亲爱的朋友:

标签: c# asp.net database entity-framework ef-code-first


【解决方案1】:

此行为取决于各种参数。首先取决于您的数据库,如 SQL Server 或 MySQL,然后取决于排序规则,如 utf8、latin1 等。

我已经在我的 MySQL 数据库上运行了这两个案例,结果如下。

型号:

public virtual string field1 { get; set; }

[StringLength(1000)]
public virtual string field2 { get; set; }

生成的迁移:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AddColumn<string>(
        name: "field1",
        table: "Category",
        nullable: true);

    migrationBuilder.AddColumn<string>(
        name: "field2",
        table: "Category",
        maxLength: 1000,
        nullable: true);
}

表格:

所以它创建了VARCHAR(1000)LONGTEXT 字段。同样,它包含的数据长度完全取决于字段的排序/编码。

LONGTEXT 大小:4,294,967,295 = (2^32−1) 字节 = 4 GiB

LONGTEXT 可以包含 4,294,967,295 字节的数据。 UTF-8 包含多字节字符。因此,如果您仅使用丹麦字符“Ø”填写该字段,您将只能获得 2,147,483,647 个字符,因为该 UTF-8 字符由两个字节组成。如果你用“a”填充它,你会得到 4,294,967,295 个字符。

【讨论】:

  • 感谢您的测试。现在我明白它是 LONGTEXT 时未指定和 VARCHAR 时。因此,让我直截了当地说,这些约束仅用于将用户限制为一定的输入长度。列是 VARCHAR(1) 还是 VARCHAR(1000) 并且所有字段都用单个字符“A”填充并不重要。它将占用相同的空间,数据将以相同的速度响应我的查询....对吗?
  • 我没有在 SQL Server 上尝试过这个。我认为当您不指定StringLength 时,它会生成为VARCHAR(MAX). So it affects the column size also it will take only 1000 characters if you specify StringLength` 为1000。如果您的列中有大量数据,您的查询会变慢。
【解决方案2】:

如果您没有在字符串属性上指定 StringLength 或 MaxLength,.net 将不会验证任何内容,但如果违反约束,数据库将抛出异常。 例如:- col1 的大小在 db 中为 100,并且您传递大小为 200 的值,它将引发 db 异常。

当您在 db 中声明大小为 1000 的列时,当以编程方式获取该列时,除非您在查询时应用修剪,否则单个字段的大小将为 2 kb。

属性主要用于声明、信息和验证目的。 属性是一个声明性标记,用于向运行时传达有关程序中各种元素(如类、方法、结构、枚举器、程序集等)的行为的信息。您可以使用属性将声明性信息添加到程序中。声明性标签由放置在其所用元素上方的方括号 ([ ]) 来描述。

属性用于向程序添加元数据,例如编译器指令和其他信息,例如 cmets、描述、方法和类。 .Net Framework 提供了两种类型的属性:预定义的属性和自定义构建的属性。

【讨论】:

  • 那么,这些约束(列的大小)不是由我的代码决定的吗?那我应该一直使用这些标签吗?
  • 如果你用它,那就更好了。流程应该始终是数据库设计到代码。无论如何,实体框架会自动生成具有相关属性的类。所以你不需要承担开销。
  • @Sumitraj CodeFirst 方法怎么样?
猜你喜欢
  • 2015-10-03
  • 2012-02-15
  • 1970-01-01
  • 2019-06-10
  • 2012-09-28
  • 1970-01-01
  • 2020-03-02
  • 1970-01-01
相关资源
最近更新 更多