Entity framework core 实体框架核心使用并发令牌修改和创建字段

Entity framework core 实体框架核心使用并发令牌修改和创建字段,entity-framework-core,optimistic-concurrency,Entity Framework Core,Optimistic Concurrency,嗨! 我有Entity Framework Core 2.xx ORM解决方案,模型中的所有对象都已创建(数据库创建时间的UTC时间戳-从未更新)和修改字段(在更新实体时始终更新)。 我读了一些关于这个非常常见的问题的建议实现,看起来框架还不能很好地支持它,因为如果不分别为每个实体定义映射,就没有好的方法来实现这一点。 我发现的一个解决方法是定义一个未映射的超类,然后用它手动生成值生成步骤。因为db UTCDatetime是db端功能,所以我还必须手动定义在db中使用utc datetime函数

嗨! 我有Entity Framework Core 2.xx ORM解决方案,模型中的所有对象都已创建(数据库创建时间的UTC时间戳-从未更新)和修改字段(在更新实体时始终更新)。 我读了一些关于这个非常常见的问题的建议实现,看起来框架还不能很好地支持它,因为如果不分别为每个实体定义映射,就没有好的方法来实现这一点。 我发现的一个解决方法是定义一个未映射的超类,然后用它手动生成值生成步骤。因为db UTCDatetime是db端功能,所以我还必须手动定义在db中使用utc datetime函数。我知道如何使用fluent api生成模型,如下所示:

AddColumn("MyObject", "Created", n => n.DateTime(nullable: false, defaultValueSql: "GETUTCDATE()"));`
//此示例缺少什么是db调用的定义:

modelBuilder.Entity<MyObject>()
        .Property(p => p.Timestamp)
        .ValueGeneratedOnAddOrUpdate()
        .IsConcurrencyToken();
但我的问题是:如果我用MyBaseObject超类自动完成所有操作,我怎么能做到这一点?(它具有这些修改和创建的字段,并且不映射自身)。目前我是这样做的,但我不知道如何定义后端创建的字段调用“GetUTCDate()”


我建议创建一个受约束的泛型方法或类,并在其中使用普通的fluentapi来配置公共属性

例如,在构造函数中接收
ModelBuilder
的泛型类:

class MyBaseObjectConfiguration<TEntity> where TEntity : MyBaseObject
{
    public MyBaseObjectConfiguration(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<TEntity>()
            .HasKey(e => e.GUID);

        modelBuilder.Entity<TEntity>()
            .Property(e => e.GUID)
            .ValueGeneratedNever();

        modelBuilder.Entity<TEntity>()
            .Property(e => e.Created)
            .ValueGeneratedOnAdd()
            .HasDefaultValueSql("GETUTCDATE()");

        modelBuilder.Entity<TEntity>()
            .Property(e => e.Modified)
            .ValueGeneratedOnAddOrUpdate()
            .HasDefaultValueSql("GETUTCDATE()")
            .IsConcurrencyToken();
    }
}

谢谢你-这实际上是我的理想发现!
class MyBaseObjectConfiguration<TEntity> where TEntity : MyBaseObject
{
    public MyBaseObjectConfiguration(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<TEntity>()
            .HasKey(e => e.GUID);

        modelBuilder.Entity<TEntity>()
            .Property(e => e.GUID)
            .ValueGeneratedNever();

        modelBuilder.Entity<TEntity>()
            .Property(e => e.Created)
            .ValueGeneratedOnAdd()
            .HasDefaultValueSql("GETUTCDATE()");

        modelBuilder.Entity<TEntity>()
            .Property(e => e.Modified)
            .ValueGeneratedOnAddOrUpdate()
            .HasDefaultValueSql("GETUTCDATE()")
            .IsConcurrencyToken();
    }
}
foreach (var type in modelBuilder.Model.GetEntityTypes().Where(t => t.ClrType.IsSubclassOf(typeof(MyBaseObject))))
    Activator.CreateInstance(typeof(MyBaseObjectConfiguration<>).MakeGenericType(type.ClrType), modelBuilder);