其他分享
首页 > 其他分享> > CodeGo.net>如何正确使用ValueGeneratedOnUpdate()?

CodeGo.net>如何正确使用ValueGeneratedOnUpdate()?

作者:互联网

我将EF Core 2.1.0-preview1-final CF方法与MS SQL Server 2014一起使用,并希望在一列中自动设置更新时间戳.我已经使用ValueGeneratedOnAdd,没有任何问题.当我将新记录插入数据库时​​,InsertDateTimeUtc列具有当前UTC日期和时间值,而UpdateDateTimeUtc列具有值0001-01-01 00:00:00.0000000,因为它是必填列.

这是我的测试模型(实体类).

public class Person
{
    public string Name { get; set; }

    public DateTime InsertDateTimeUtc { get; set; }

    public DateTime UpdateDateTimeUtc { get; set; }


    public static void OnModelCreating(ModelBuilder modelBuilder)
    {
        var entity = modelBuilder.Entity<Person>();

        entity.Property(p => p.Name)
              .IsRequired();

        entity.Property(p => p.InsertDateTimeUtc)
              .HasDefaultValueSql("GETUTCDATE()")
              .ValueGeneratedOnAdd()
              .IsRequired();

        entity.Property(p => p.UpdateDateTimeUtc)
              .HasDefaultValueSql("GETUTCDATE()")
              .ValueGeneratedOnUpdate()
              .IsRequired();
    }
}

据我测试ValueGeneratedOnUpdate不能按预期工作.如果我更新一条记录,我希望UpdateDateTimeUtc列将获取当前的UTC日期和时间值,但不会改变.记录(属性名称)将成功更新-我为属性名称设置了另一个值,可以对其进行评估.

我发现this SO answer包含以下引号,似乎来自此MS doc article – Generated Values.

This just lets EF know that values are generated for added or updated entities, it does not guarantee that EF will setup the actual mechanism to generate values.

但是在提到的MS doc文章中,我找不到有关ValueGeneratedOnUpdate用法的任何信息.我已经尝试使用ValueGeneratedOnAddOrUpdate-也没有成功.

好吧,有人暗示我如何在代码中自动设置数据库中UpdateDateTimeUtc列的值而无需任何逻辑(例如person.UpdateDateTimeUtc = DateTime.UtcNow;)?还是可以向某人提供我可以阅读更多信息的链接?

解决方法:

Generated values文档主题(问题中提到的链接)包含以下警告:

How the value is generated for added and updated entities will depend on the database provider being used. Database providers may automatically setup value generation for some property types, while others will require you to manually setup how the value is generated.

For example, when using SQL Server, byte[] properties that are set as generated on add or update and marked as concurrency tokens, will be setup with the rowversion data type – so that values will be generated in the database. However, if you specify that a DateTime property is generated on add or update, then you must setup a way for the values to be generated. One way to do this, is to configure a default value of GETDATE() (see Default Values) to generate values for new rows. You could then use a database trigger to generate values during updates (such as the following example trigger).

然后是示例触发代码.

因此,基本上,您应该为更新创建价值生成触发器.更新记录(类似于标识和计算列)后,EF Core只会从数据库中读取值.

在您的示例中,修改生成的Migration Up方法,如下所示:

migrationBuilder.CreateTable(
    name: "Person",
    columns: table => new
    {
        Id = table.Column<int>(nullable: false)
            .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
        InsertDateTimeUtc = table.Column<DateTime>(nullable: false, defaultValueSql: "GETUTCDATE()"),
        Name = table.Column<string>(nullable: false),
        UpdateDateTimeUtc = table.Column<DateTime>(nullable: false, defaultValueSql: "GETUTCDATE()")
    },
    constraints: table =>
    {
        table.PrimaryKey("PK_Person", x => x.Id);
    });

// Add the following:   
migrationBuilder.Sql(
@"CREATE TRIGGER [dbo].[Person_UPDATE] ON [dbo].[Person]
    AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;

    IF ((SELECT TRIGGER_NESTLEVEL()) > 1) RETURN;

    DECLARE @Id INT

    SELECT @Id = INSERTED.Id
    FROM INSERTED

    UPDATE dbo.Person
    SET UpdateDateTimeUtc = GETUTCDATE()
    WHERE Id = @Id
END");

标签:ef-code-first,entity-framework-core,c
来源: https://codeday.me/bug/20191109/2011890.html