【发布时间】:2019-04-02 06:37:33
【问题描述】:
我有点惊讶我没有找到关于以下问题的任何信息,所以如果我在文档中的某个地方错过了它,请原谅。使用 SQL Server(2016 本地和 Azure)和 EFCore Code First,我们尝试创建一个具有持久值的计算表列。创建列工作正常,但我不知道如何保留该值。以下是我们的工作:
modelBuilder.Entity<SomeClass>(entity =>
{
entity.Property(p => p.Checksum)
.HasComputedColumnSql("(checksum([FirstColumnName], [SecondColumnName]))");
});
这就是我们真正希望在 T-SQL 中获得的内容:
CREATE TABLE [dbo].[SomeClass]
(
[FirstColumnName] [NVARCHAR](10)
, [SecondColumnName] [NVARCHAR](10)
, [Checksum] AS (CHECKSUM([FirstColumnName], [SecondColumnName])) PERSISTED
);
谁能指出我正确的方向?
提前致谢,托比
更新:基于@jeroen-mostert 的一个好主意,我还尝试将PERSISTED 字符串作为公式的一部分传递:
modelBuilder.Entity<SomeClass>(entity =>
{
entity.Property(p => p.Checksum)
.HasComputedColumnSql("(checksum([FirstColumnName], [SecondColumnName]) PERSISTED)");
});
还有括号外:
modelBuilder.Entity<SomeClass>(entity =>
{
entity.Property(p => p.Checksum)
.HasComputedColumnSql("(checksum([FirstColumnName], [SecondColumnName])) PERSISTED");
});
然而令人惊讶的是,计算列仍然是用Is Persisted = No 生成的,所以PERSISTED 字符串似乎被忽略了。
【问题讨论】:
-
请注意,
CHECKSUM对于大多数用途都是不利的,直到并包括用作哈希索引的基础,尽管您可以为此目的使用它,因为重复项不太可能有性能影响大。如果您打算将它用于哈希索引,则不需要PERSISTED,因为它将作为索引的一部分保留。如果不是哈希索引,请考虑使用HASHBYTES更好的校验和算法。 -
感谢您提供的信息。现在我们正在使用该列来检查两个不同表中具有匹配 ID 值的行的差异。从您的评论中,我得出结论,最好将 HASHBYTES 用于 eaxmple,因此我将对此进行研究。但是,原始问题仍然存在,因为无论校验和算法如何,我还想保留计算列。
-
冒着说些蠢话的风险,你有没有检查过如果你简单地将
PERSISTED添加到方法中的定义会发生什么?我怀疑 EF 是否进行任何解析或解释,并且它不需要知道该列是否物理持久化(它只需要知道它是计算的)。 -
这听起来一点也不愚蠢,但不幸的是,它似乎不起作用。
-
“似乎不起作用”以什么方式?它会出错吗? EF 是否不迁移现有列? (如果将定义视为黑匣子,这或多或少是意料之中的。)如果从头开始,它会生成计算的列而不是持久的列吗? (这让我感到惊讶,因为这意味着 EF 会解析定义并竭尽全力忽略
PERSISTED。)
标签: sql-server entity-framework-core