实体框架核心:具有持久值的计算列

时间:2018-10-29 10:36:27

标签: sql-server entity-framework-core

我对以下问题未找到任何信息感到有些惊讶,因此,如果我在文档中的某处未找到任何信息,请原谅。使用SQL Server(2016年在本地和Azure上使用)和EFCore代码首先,我们尝试创建具有持久值的计算表列。创建该列可以很好地工作,但是我不知道如何保持该值。这是我们的工作:

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
);

有人能指出我正确的方向吗?

预先感谢,Tobi

更新:基于@ 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字符串似乎只是被忽略了。

2 个答案:

答案 0 :(得分:1)

在进行了一些阅读和测试之后,我最终在SQL查询中尝试了PERSISTED并成功了。

entity.Property(e => e.Duration_ms)
      .HasComputedColumnSql("DATEDIFF(MILLISECOND, 0, duration) PERSISTED");

生成的迁移如下:

migrationBuilder.AddColumn<long>(
            name: "duration_ms",
            table: "MyTable",
            nullable: true,
            computedColumnSql: "DATEDIFF(MILLISECOND, 0, duration) PERSISTED");

要检查数据库是否确实存在,我运行以下命令:

select is_persisted, name from sys.computed_columns where is_persisted = 1

和我创建的列在那里。

答案 1 :(得分:0)

" 您还可以指定存储计算列(有时称为持久化),这意味着它在行的每次更新时计算,并与常规列一起存储在磁盘上:"

modelBuilder.Entity<SomeClass>(entity =>
{
     entity.Property(p => p.Checksum)
    .HasComputedColumnSql("(checksum([FirstColumnName], [SecondColumnName]), stored: true);
});

这是从 Microsoft Docs 中获取(并稍作修改)。:https://docs.microsoft.com/en-us/ef/core/modeling/generated-properties?tabs=data-annotations#computed-columns