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 上的每个查询上计算?的主要内容,如果未能解决你的问题,请参考以下文章
为 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 中的多对多实体