首页 > 解决方案 > EF Core 3 具有价值生成器

问题描述

在实体的 modelBUilder 中,我尝试通过自定义生成器在添加和更新时设置创建和修改日期。走这条路的原因是因为创建模型的 DbContext 被用作基类。此基类由 SQL Server 和 SQLite EFCore 扩展继承。因此,上下文中应该有数据库显式功能。最初实现 SQL Server 的 GetDateUTC() 和触发器。

modelBuilder.Entity<CommunicationSendRequest>(entity =>
            {
               ...

                entity.Property(p => p.CreatedAt).ValueGeneratedOnAdd().HasValueGenerator<CreatedAtTimeGenerator>();
                entity.Property(p => p.ModifiedAt).ValueGeneratedOnUpdate().HasValueGenerator<ModifiedAtTimeGenerator>();

            });

但是在添加和更新两个属性时发生的事情总是设置为新值。对全新插入的含义设置了 modifiedat,在更新时设置了 createdat 日期。这将删除日期创建的真实值。

CreatedAt 和 Modifiedat 日期

问题是那些价值生成器设置正确吗?有没有办法使用生成器来完成这个?在生成器中,我还尝试检查状态并仅在添加或修改状态时才返回值。但是状态总是等于分离。

 public class CreatedAtTimeGenerator : ValueGenerator<DateTimeOffset>
    {
        public override DateTimeOffset Next(EntityEntry entry)
        {
            if (entry == null)
            {
                throw new ArgumentNullException(nameof(entry));
            }

            return DateTimeOffset.UtcNow;
        }

        public override bool GeneratesTemporaryValues { get; }
    }
    public class ModifiedAtTimeGenerator : ValueGenerator<DateTimeOffset>
    {
        public override DateTimeOffset Next(EntityEntry entry)
        {
            if (entry == null)
            {
                throw new ArgumentNullException(nameof(entry));
            }

            return DateTimeOffset.UtcNow;
        }

        public override bool GeneratesTemporaryValues { get; }
    }

标签: entity-frameworkef-code-firstef-core-3.1

解决方案


我实际上所做的是完全摆脱 ValueGenerate 的概念,并通过覆盖 SaveChanges() 方法来处理 CreatedAt、ModifiedAt 的创建,并在创建这篇文章后添加 DeletedAt 日期。

 public override int SaveChanges()
    {
        var selectedEntityList = ChangeTracker.Entries()
            .Where(x => (x.Entity is IEntityCreatedAt ||
                         x.Entity is IEntityModifiedAt ||
                         x.Entity is IEntityIsDeleted) &&
                        (x.State == EntityState.Added || x.State == EntityState.Modified)).ToList();

        selectedEntityList.ForEach(entity =>
        {
            if (entity.State == EntityState.Added)
            {
                if (entity.Entity is IEntityCreatedAt)
                    ((IEntityCreatedAt)entity.Entity).CreatedAt = DateTimeOffset.UtcNow;
            }

            if (entity.State == EntityState.Modified)
            {
                if (entity.Entity is IEntityModifiedAt)
                    ((IEntityModifiedAt)entity.Entity).ModifiedAt = DateTimeOffset.UtcNow;

                if (entity.Entity is IEntityIsDeleted)
                    if (((IEntityIsDeleted)entity.Entity).IsDeleted)
                        ((IEntityIsDeleted)entity.Entity).DeletedAt = DateTimeOffset.UtcNow;
            }
        });

        return base.SaveChanges();
    }

推荐阅读