【问题标题】:Why is Entity Framework generating the [Required] attribute on my computed column?为什么实体框架会在我的计算列上生成 [Required] 属性?
【发布时间】:2019-05-31 17:12:38
【问题描述】:

简化示例:我有一个计算列定义为我的 Azure SQL 服务器表中的一个字段。

CREATE TABLE [dbo].[MyTable] 
(
  [Id] INT NOT NULL PRIMARY KEY IDENTITY,
  [CancelledOn] DATETIME NULL,
  [MyComputedColumn] AS CASE WHEN ([CancelledOn] IS NOT NULL) THEN 'Cancelled' ELSE 'Draft' END
)

但是当我在 Visual Studio 2017 中生成代码优先的 ADO.NET 实体数据模型时,生成的属性同时具有 [Required][DatabaseGenerated(DatabaseGeneratedOption.Computed)] 属性。

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Required]
[StringLength(19)]
public string MyComputedColumn { get; set; }

当然,这会导致实体验证错误和其他各种问题。

当 EF 也知道它是一个计算域时,为什么还要将此属性标记为 [Required]

我知道我可以只删除该属性,但我正在寻找一种更简洁的解决方案,而不是每次重新生成实体模型时都必须从所有计算列中手动删除 [Required] 属性。例如,我可以在 SQL 中以不同的方式声明该列吗?

【问题讨论】:

  • 您是否尝试过在计算机列中添加 NULL ?
  • 根据 MyComputedColumn 的逻辑,它不为空,因此 EF 将其标记为必需。
  • @Zain 显然我不能... SQL46011:只能在计算列上创建唯一或主键约束,而检查、外键和非空约束要求计算列被持久化。

标签: c# sql-server visual-studio entity-framework ef-code-first


【解决方案1】:

尽管我们知道根据您使用的逻辑计算列永远不会为空,但 EF 并不是那么聪明,因此您应该使计算列可以为空,即使它永远不会为空。

【讨论】:

  • 我试图使它可以为空但不能... SQL46011:只能在计算列上创建唯一或主键约束,而检查、外键和非空约束要求计算列被坚持。这应该是可能的吗?如果有,怎么做?
  • 是的,你可以持久化计算列:stackoverflow.com/a/45727264/2283168
【解决方案2】:

感谢@Shan 的评论让我朝着正确的方向前进:

根据 MyComputedColumn 的逻辑,它不为空,因此 EF 将其标记为 必填。

我不能像其他人建议的那样将列设为 NULLABLE,所以我必须在计算列中添加一个不可能的 NULL 情况:

[MyComputedColumn] AS CASE 
  WHEN 2 = 1 THEN NULL 
  WHEN [CancelledOn] IS NOT NULL THEN 'Cancelled' 
  ELSE 'Draft' END

这有点骇人听闻,我希望 EF 更智能,但它不再生成 [Required],所以它适用于我的目的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 2012-10-26
    相关资源
    最近更新 更多