如何在添加和更新记录时使用Entity Framework自动生成字段?

huangapple go评论73阅读模式
英文:

How to automatically generate fields using Entity Framework when adding and updating records?

问题

I'm having trouble making the "CreatedAt" and "ModifiedAt" fields automatically generated by Entity Framework when adding and updating records in a table. I've tried using the "ValueGeneratedOnAddOrUpdate()" property in my code, but it's not working as expected.

Here's the relevant snippet of my code:

using FazendaEletronica.Domain.Entity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace FazendaEletronica.Infra.Data.EntitiesConfiguration
{
    public class AnimalConfiguration : IEntityTypeConfiguration<Animal>
    {
        public void Configure(EntityTypeBuilder<Animal> builder)
        {
            builder.HasKey(t => t.Id);
            builder.Property(p => p.Number).IsRequired();
            builder.Property(p => p.SurName).HasMaxLength(100);
            builder.Property(p => p.BirthDay).IsRequired().HasColumnType("Date");
            builder.Property(p => p.CharAnimalSex).HasMaxLength(1).IsRequired();
            builder.Property(p => p.AnimalStatus).IsRequired();
            builder.Property(p => p.Active).IsRequired().HasColumnType("bit");
            builder.Property(p => p.SaleDate).HasColumnType("Date");
            builder.HasOne(a => a.AnimalDad).WithMany(a => a.AnimalsDad).HasForeignKey(a => a.AnimalDadId).IsRequired(false);
            builder.HasOne(p => p.AnimalClass).WithMany(a => a.Animals).HasForeignKey(f => f.AnimalClassId).IsRequired();
            builder.HasOne(p => p.AnimalPurpose).WithMany(a => a.Animals).HasForeignKey(f => f.AnimalPurposeId).IsRequired();
            builder.HasOne(p => p.UserFarm).WithMany(p => p.Animals).HasForeignKey(f => f.UserFarmId).IsRequired();

            builder.Property(p => p.ModifiedAt).ValueGeneratedOnAddOrUpdate();
            builder.Property(p => p.CreatedAt).ValueGeneratedOnAdd();
        }
    }
}

Could someone help me understand why the "ValueGeneratedOnAddOrUpdate()" property is not automatically generating the values? Is there any other approach I can take to achieve this result?

he ValueGeneratedOnAddOrUpdate() method in Entity Framework Core is used to configure a property to have its value automatically generated when a new record is inserted or updated. However, the behavior you are experiencing might be due to the fact that ValueGeneratedOnAddOrUpdate() is not supported for all property types.

英文:

I'm having trouble making the "CreatedAt" and "ModifiedAt" fields automatically generated by Entity Framework when adding and updating records in a table. I've tried using the "ValueGeneratedOnAddOrUpdate()" property in my code, but it's not working as expected.

Here's the relevant snippet of my code:

using FazendaEletronica.Domain.Entity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace FazendaEletronica.Infra.Data.EntitiesConfiguration
{
    public class AnimalConfiguration : IEntityTypeConfiguration&lt;Animal&gt;
    {
        public void Configure(EntityTypeBuilder&lt;Animal&gt; builder)
        {
            builder.HasKey(t =&gt; t.Id);
            builder.Property(p =&gt; p.Number).IsRequired();
            builder.Property(p =&gt; p.SurName).HasMaxLength(100);
            builder.Property(p =&gt; p.BirthDay).IsRequired().HasColumnType(&quot;Date&quot;);
            builder.Property(p =&gt; p.CharAnimalSex).HasMaxLength(1).IsRequired();
            builder.Property(p =&gt; p.AnimalStatus).IsRequired();
            builder.Property(p =&gt; p.Active).IsRequired().HasColumnType(&quot;bit&quot;);
            builder.Property(p =&gt; p.SaleDate).HasColumnType(&quot;Date&quot;);
            builder.HasOne(a =&gt; a.AnimalDad).WithMany(a =&gt; a.AnimalsDad).HasForeignKey(a =&gt; a.AnimalDadId).IsRequired(false);
            builder.HasOne(p =&gt; p.AnimalClass).WithMany(a =&gt; a.Animals).HasForeignKey(f =&gt; f.AnimalClassId).IsRequired();
            builder.HasOne(p =&gt; p.AnimalPurpose).WithMany(a =&gt; a.Animals).HasForeignKey(f =&gt; f.AnimalPurposeId).IsRequired();
            builder.HasOne(p =&gt; p.UserFarm).WithMany(p =&gt; p.Animals).HasForeignKey(f =&gt; f.UserFarmId).IsRequired();

            builder.Property(p =&gt; p.ModifiedAt).ValueGeneratedOnAddOrUpdate();
            builder.Property(p =&gt; p.CreatedAt).ValueGeneratedOnAdd();
        }
    }
}

Could someone help me understand why the "ValueGeneratedOnAddOrUpdate()" property is not automatically generating the values? Is there any other approach I can take to achieve this result?

he ValueGeneratedOnAddOrUpdate() method in Entity Framework Core is used to configure a property to have its value automatically generated when a new record is inserted or updated. However, the behavior you are experiencing might be due to the fact that ValueGeneratedOnAddOrUpdate() is not supported for all property types.

答案1

得分: 0

一个选项是在 DataContext.OnSaveChanges 中处理它,使用基类来识别要自动处理的实体:

public abstract class EditableEntityBase
{
    [DateTimeKind(DateTimeKind.Local), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime CreatedAt { get; set; }
    [DateTimeKind(DateTimeKind.Local), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime LastModAt { get; set; }
}

/// <summary>
/// 用于保存更改的实现覆盖。这确保了记录了CreatedBy/At和ModifiedBy/At。
/// </summary>
public override int SaveChanges()
{
    // 可选,如果您想要一个软删除系统(例如,IsActive=false而不是Delete... 
    // 这些DbContexts不允许硬删除。
    if (ChangeTracker.Entries().Any(x => x.State == EntityState.Deleted
            && typeof(EditableEntityBase).IsAssignableFrom(x.GetType())))
        throw new ApplicationException("不支持硬删除。");

    var updatedEntities = ChangeTracker.Entries()
        .Where(x => x.State == EntityState.Modified)
        .Select(x => x.Entity)
        .Cast<EditableEntityBase>();
    foreach (var entity in updatedEntities)
    {
        entity.LastModAt = DateTime.Now;
    }

    var insertedEntities = ChangeTracker.Entries()
        .Where(x => x.State == EntityState.Added)
        .Select(x => x.Entity)
        .Cast<EditableEntityBase>();
    foreach (var entity in insertedEntities)
    {
        entity.CreatedAt = entity.LastModAt = DateTime.Now;
    }

    return base.SaveChanges();
}

希望这对你有所帮助!

英文:

One option is to handle it in the DataContext.OnSaveChanges using a base class to identify which entities you want to automatically handle:

public abstract class EditableEntityBase
{
    [DateTimeKind(DateTimeKind.Local), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime CreatedAt { get; set; }
    [DateTimeKind(DateTimeKind.Local), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime LastModAt { get; set; }
}

/// &lt;summary&gt;
/// Implementation override for saving changes. This ensures that CreatedBy/At
/// and ModifiedBy/At are recorded.
/// &lt;/summary&gt;
public override int SaveChanges()
{
    // Optional if you want a soft-delete system (I.e. IsActive=false rather than Delete...
    // These DbContexts do not allow for hard Deletes. 
    if (ChangeTracker.Entries().Any(x =&gt; x.State == EntityState.Deleted
            &amp;&amp; typeof(EditableEntityBase).IsAssignableFrom(x.GetType())))
        throw new ApplicationException(&quot;Hard deletes are not supported.&quot;);

    var updatedEntities = ChangeTracker.Entries()
        .Where(x =&gt; x.State == EntityState.Modified)
        .Select(x =&gt; x.Entity)
        .Cast&lt;EditableEntityBase&gt;();
    foreach (var entity in updatedEntities)
    {
        entity.LastModAt = DateTime.Now;
    }

    var insertedEntities = ChangeTracker.Entries()
        .Where(x =&gt; x.State == EntityState.Added)
        .Select(x =&gt; x.Entity)
        .Cast&lt;EditableEntityBase&gt;();
    foreach (var entity in insertedEntities)
    {
        entity.CreatedAt = entity.LastModAt = DateTime.Now;
    }

    return base.SaveChanges();
}

huangapple
  • 本文由 发表于 2023年6月12日 08:05:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76452977.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定