EF Core (< 5.0) HasComputedColumnSql - 在插入/更新或 SQL Server/AzureSQL 上的每个查询上计算?

Posted

技术标签:

【中文标题】EF Core (< 5.0) HasComputedColumnSql - 在插入/更新或 SQL Server/AzureSQL 上的每个查询上计算?【英文标题】:EF Core (< 5.0) HasComputedColumnSql - computed on Insert/Update or each query on SQL Server / AzureSQL? 【发布时间】:2017-10-25 13:24:35 【问题描述】:

注意:这个问题引用了一个 old EF Core 问题。有关与 EF Core 5 相关的讨论,请参阅 this answer。

我看到关于此的相互矛盾的信息。 LearnEntityFrameworkCore.com说可以写

.HasComputedColumnSql("GetUtcDate()");

每当创建或更新行时,该列的值由数据库的 GetUtcDate() 方法生成

但是,在 SQL Server 上的计算列的 technet 文档中它说:

每次在查询中引用它们时都会重新计算它们的值。

【问题讨论】:

【参考方案1】:

您引用的两个文档是正确的。每个人都在谈论不同的方法。此方法有几个重载。您可以通过here 进行检查(在浏览器中搜索“HasComputedColumnSql”)。

如果数据库中有定义此列值的触发器,您将使用HasComputedColumnSql() 实现。

如果您想在属性上存储计算值,但不希望它持久存在于表中,您将使用HasComputedColumnSql("SomeFunction()") 实现。

如果您想将值存储在列中,您将使用实现HasComputedColumnSql("SomeFunction()", stored: true)

【讨论】:

好吧,我引用的文档已有 4 年历史了 :) 如果您查看您发送的链接,但将“版本”下拉设置为 EF Core 2.0,您会看到这些重载允许stored: true 还没有。很高兴看到从那时起,两个主要版本都解决了这个差距! 我更新了标题和问题以提供清晰的说明:) 再次感谢您的更新!【参考方案2】:

好问题。从 EF Core 文档中不清楚 HasComputedColumnSql 代表什么类型的计算列。可能是因为它是关系扩展的一部分,因此被认为是特定于提供者的。但由于它没有配置选项,我同意应该指定行为。

对 SQL Server 的快速测试表明,创建的列不是物理存储的(没有使用PERSISTED 选项),实际上它不能,因为GetUtcDate 不是确定性的。因此,第一个链接中的 LastModified 示例不正确 - 该列将在任何时候被读取时重新计算,因此它不能用于所需的意图,并且应该作为普通列创建并由代码更新。

看起来 EF Core 中的预期用途是允许基于其他列(如 FullName)进行简单计算,或使用数据库特定的转换函数与未正确存储的数据(例如存储为文本的数字/日期时间数据)等。

【讨论】:

有趣的是,在 EF Core 代码中,包括 SqlServer 特定的模型工厂,计算列被设置/建模为ValueGenerated.OnAddOrUpdate。如果将来他们可以使用它(用户可以通过PropertyBuilder.ValueGeneratedOnAddOrUpdate() 扩展设置)为非确定性计算列创建触发器或将PERSISTED 属性添加到确定性列,我可以看到价值。现在,如果你想效仿这个概念,你基本上必须在迁移中自己触发。 确实如此。在那之前,ValueGeneratedOnAddOrUpdate 结合HasValueGenerator 和自定义ValueGenerator 类可用于在客户端实现类似的功能。 或者可能不是 - 我似乎无法让价值生成器方法发挥作用。在 EF Core 中还有很多事情要做才能使其可用:) 不幸的是,这种策略看起来根本行不通。查看HasValueGenerator,仅在添加实体时才调用它。此外,他们目前没有任何改变这一点的计划,如下所示:github.com/aspnet/EntityFramework/issues/6999

以上是关于EF Core (< 5.0) HasComputedColumnSql - 在插入/更新或 SQL Server/AzureSQL 上的每个查询上计算?的主要内容,如果未能解决你的问题,请参考以下文章

EF Core 5.0 添加多对多使得一对多无法确定

为 ASP.NET Core 5.0 - EF Core 5.0 Web App 配置 PostgreSQL 连接字符串以在 MS 或 Linux 云上运行?

.NET Core 5.0 EF Migration 添加新的外部列

EF Core 5.0 - 更新 ASP.NET Core Web API 中的多对多实体

EF Core 5.0 - 更改“定义查询”映射实体时是不是需要生成迁移?

EF Core 5.0 中的多对多关系是不是可以配置为仅保留一个导航属性(在一侧)?