gpt4 book ai didi

c# - 标记为只读的 EF 核心计算属性

转载 作者:行者123 更新时间:2023-11-30 19:24:13 25 4
gpt4 key购买 nike

背景:每当添加或更新“Item”实体时,我将覆盖 SaveChanges() 方法以自动生成 LastUpdatedDate。

Item.cs

  [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime? LastUpdated { get; set; }

数据库上下文

  protected override void OnModelCreating(ModelBuilder modelBuilder)
{
...
// generated value
modelBuilder.Entity<Item>()
.Property(b => b.LastUpdated)
.ValueGeneratedOnAddOrUpdate();

}

public override int SaveChanges()
{
var now = DateTime.UtcNow;

foreach (var item in ChangeTracker.Entries<Item>()
.Where(e => e.State == EntityState.Added || e.State == EntityState.Modified))
{
item.Property("LastUpdated").CurrentValue = now;
}

return base.SaveChanges();
}

我遇到的问题是每当调用 SaveChanges() 时我都会收到此异常:

An exception of type 'System.InvalidOperationException' occurred in EntityFramework.Core.dll but was not handled in user code.
Additional information: The property 'LastUpdated' on entity type 'Item' is defined to be read-only after it has been saved, but its value has been modified or marked as modified.

要解决此问题,我必须设置 IsReadOnlyBeforeSave 和 IsReadOnlyAfterSave为假,如下所示:

        modelBuilder.Entity<Tray>()
.Property(b => b.LastUpdated)
.ValueGeneratedOnAddOrUpdate()
.Metadata.IsReadOnlyBeforeSave = false;
modelBuilder.Entity<Tray>()
.Property(b => b.LastUpdated)
.Metadata.IsReadOnlyAfterSave = false;

问题:

这是在 EF Core 中设置计算属性的正确方法吗?

此外,我能否首先阻止 LastUpdated 被定义为“只读”?

最佳答案

Is this the correct way to setup computed properties in EF Core?

documentation对此很清楚:

Value generated on add or update means that a new value is generated every time the record is saved (insert or update).

Caution

How the value is generated for added and updated entities will depend on the database provider being used. (...) 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 (such as a database trigger).

注解的名称——“DatabaseGeneratedOption”——可能已经揭示了一些类似的东西。

因此,如果您想使用此模式,您应该在数据库中设置一个触发器,用于在插入和每次更新时设置字段值。通过使用注释 [DatabaseGenerated] 流畅的 API .ValueGeneratedOnAddOrUpdate()(不需要两者都做),EF 被告知它应该保存更改后从数据库中读取值。

至于 IsReadOnlyBeforeSave 属性。到目前为止唯一的文档是 EF 源代码中关于属性的 XML 文档:

Gets or sets a value indicating whether or not this property can be modified before the entity is saved to the database. If true, an exception will be thrown if a value is assigned to this property when it is in the Added state.

据我所知,您可能希望将此值设置为 true 以消除任何认为设置此属性有用的期望(因为它没有用)。同样,您可以将 IsReadOnlyAfterSave 设置为在现有(而非 Added)实体中设置该属性时抛出异常。

如果您不想要数据库生成的值,您可以删除注释并像现在一样分配值。

关于c# - 标记为只读的 EF 核心计算属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39278432/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com