ChW*_*ChW 5 c# ef-code-first entity-framework-core
我将EF Core 2.1.0-preview1-final CF方法与MS SQL Server 2014一起使用,并希望在一列中自动设置更新时间戳。我已经使用了,ValueGeneratedOnAdd没有任何问题。当我在数据库中插入新记录时,该InsertDateTimeUtc列具有当前UTC日期和时间值,该UpdateDateTimeUtc列具有value 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();
}
}
Run Code Online (Sandbox Code Playgroud)
据我测试ValueGeneratedOnUpdate无法正常工作。如果我更新一条记录,我希望该列UpdateDateTimeUtc将获得当前的UTC日期和时间值,但不会改变。记录(property Name)将成功更新-我为property设置了另一个值Name,可以对其进行评估。
我可以找到包含以下引号的SO答案,该引号似乎来自此MS doc文章-Generated Values。
这只是让EF知道为添加或更新的实体生成了值,并不保证EF将设置实际的机制来生成值。
但是在提到的MS doc文章中,我找不到有关的用法的任何信息ValueGeneratedOnUpdate。我已经尝试使用ValueGeneratedOnAddOrUpdate-也没有成功。
好吧,有人暗示我如何UpdateDateTimeUtc在没有person.UpdateDateTimeUtc = DateTime.UtcNow;代码逻辑的情况下自动为数据库中的列设置值?还是可以向某人提供我可以阅读更多信息的链接?
该产生的值文档主题(该链接问题中提及)包含以下警告:
如何为添加和更新的实体生成值将取决于所使用的数据库提供程序。数据库提供程序可能会自动设置某些属性类型的值生成,而其他提供程序则需要您手动设置值的生成方式。
例如,当使用SQL Server时,将使用rowversion数据类型设置在添加或更新时设置为在添加或更新时生成并标记为并发标记的byte []属性-以便在数据库中生成值。但是,如果指定在添加或更新时生成DateTime属性,则必须设置一种生成值的方式。一种方法是配置GETDATE()的默认值(请参见默认值)以为新行生成值。然后,您可以使用数据库触发器在更新过程中生成值(例如以下示例触发器)。
然后是示例触发代码。
因此,基本上,您应该为更新创建价值生成触发器。更新记录(类似于标识和计算列)后,EF Core只会从数据库中读取值。
在您的示例中,修改生成的迁移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");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1554 次 |
| 最近记录: |