哪些表应该有时间戳列?使用 Entity Framework、XAF、DDD 进行并发检查

Which tables should have a timestamp column? Concurrency check with Entity Framework, XAF, DDD

我正在使用 Dev Express XAF WinForms 编写 ERP 系统。

在实践中,我发现我的 DBContext 需要为我的大部分业务对象提供一个 DBSet。

我正在尝试找出哪些 table 应该具有用于​​乐观并发目的的时间戳列。

例如我有

[NavigationItem("Sales")]
public class SalesOrder : BaseSalesHeader 
{
    public SalesOrder()
    {
       Lines = new List<SalesOrderLine>();
    }
    [Aggregated]
    public virtual List<SalesOrderLine> Lines { get; set; }  
}

[NavigationItem("Production")]
 public class SalesOrderLine : BaseSalesProductTransactionLine 
{

    [Browsable(false)]
    [System.ComponentModel.DataAnnotations.Required]  
    [RuleRequiredField(DefaultContexts.Save)]
    [ForeignKey("SalesOrder_Id")]
    public virtual SalesOrder SalesOrder { get; set; }
}

在我的 DBContext 中我有

    public DbSet<SalesOrder> SalesOrders { get; set; }
    public DbSet<SalesOrderLine> SalesOrderLines { get; set; }

在我的 OnModelCreating 中我有

    modelBuilder.Entity<SalesOrder>().HasMany(p => p.Lines).WithRequired(t => t.SalesOrder).WillCascadeOnDelete(true);

可从 2 个菜单访问销售订单行 作为销售订单的一部分,并作为生产导航项下的销售订单行项目。

我想我应该在 SalesOrders 中包含时间戳字段 table。我是否也应该在 SalesOrderLine table 中包含它?

这里是linked question at Dev Express Support

任何可以由 1 个以上用户同时更新的 table 都应该有某种与之关联的时间戳。就个人而言,我在每个 table 上都加上了时间戳,只是为了加倍确定。

您可以使用 [Timestamp] 属性标记此时间戳字段,EF 将自动知道如何处理它。

您是否要为实体应用乐观并发 (OC) 我们无法为您决定。但是有一些事情需要考虑:

  • 不一定只有公开为 DbSet 的实体才需要 OC。毕竟,任何映射实体在可通过导航属性访问时都可以更改。 SalesOrder 通过它的 Line 属性 暴露了 SalesOrderLines,所以无论如何你可以创建一些 UI 只修改 SalesOrderLines 而它只接收 SalesOrder(包括其行)作为输入。
  • 在 Entity Framework(和其他 ORM)中,当其中一个子项被修改时,父项不会被标记为已修改。如果您保存 SalesOrder 并修改了 SalesOrderLines,则只有这些行的更新语句。

所以,是的,你可能也想通过 OC 来保护 SalesOrderLine。但也要考虑一下:

  • OC 不是免费的。当您将 RowVersion* 列添加到 table(和 )时,Entity Framework 将在每次插入或更新后读取其值。我经历过,这可能会大大损害更新相对较多记录的进程的性能(EF 无论如何都不会发光)。此外,当并发冲突发生时,EF 将从数据库中读取冲突记录的当前值。

我见过一些应用程序,其中通过在修改其任何子对象时将父对象(具有 OC)标记为已修改来减轻 OC 对性能的影响。我认为这有点做作,但可能需要考虑一下。


* TimeStamp 是已弃用的数据类型