.net EFCore ValueObject未将父项标记为已更改?

4smxwvx5  于 2023-05-30  发布在  .NET
关注(0)|答案(3)|浏览(149)

你好,我有一个实体“人”。使用“Alias”Value对象

public partial class Person : BaseEntity, IAggregateRoot
{
  public Alias Alias { get; set; }
  //..other properties...

}

PersonConfiguration.cs

entity.OwnsOne(o => o.Alias, a =>
{
   a.WithOwner(x=>x.Person);
});

别名

public class Alias :ValueObject
{
 public string FirstName { get; private set; }
 public string MiddleName { get; private set; }
 public string LastName { get; private set; }
}

如果我对Alias上的某个属性进行了更改- Change FirstName -它不会在更改跟踪器中将该Person标记为已更改。我已经用变更跟踪器完成了我的审计。因此,如果我只是更改Alias上的属性,则不会设置上次更新日期和用户。
我能做些什么来弥补吗?
谢谢你。

cbeh67ev

cbeh67ev1#

找到了一种方法-不是很兴奋,但它的工作..

var ownedEntries = _context.ChangeTracker.Entries<ValueObject>().Where(f => f.Metadata.IsOwned() && f.State == EntityState.Modified).ToList();
foreach (var item in ownedEntries)
{
    var ownedNavigations = item.Metadata.GetNavigations().Where(n => n.ForeignKey.IsRequiredDependent).ToList();
    foreach (var nav in ownedNavigations)
    {
        var ownerEntry = item.Reference(nav.Name).TargetEntry;
        if (ownerEntry != null)
        {
            // Get the owner entity using reflection
            var ownerEntity = ownerEntry.Entity
            // Set the owner entity as modified
            var ownerEntryType = ownerEntry.GetType();
            var stateProperty = ownerEntryType.GetProperty("State", BindingFlags.Public | BindingFlags.Instance);
            stateProperty?.SetValue(ownerEntry, EntityState.Modified);
        }
    }
}
mbjcgjjk

mbjcgjjk2#

值对象应该是不可变的。在创建值对象之后,不应该更改它的属性。
不要更改Alias的属性,而是替换它。

人员

Person.Alias = new Alias("John", "Robert", "Smith");
// Change name
Person.Alias = Person.Alias.ChangeFirstName("Dave");

别名(使用init setter强制不变性)

public string FirstName { get; init; }
public string MiddleName { get; init; }
public string Surname { get; init; }

public Alias(string firstName, string middleName, string surname)
{
    FirstName = firstName;
    MiddleName = middleName;
    Surname = surname;
}

public Alias ChangeFirstName(string newFirstName) =>
    new Alias(newFirstName, MiddleName, Surname);
szqfcxe2

szqfcxe23#

创建EntityEntry扩展

public static bool HasChangedOwnedEntities(this EntityEntry entry)
   => entry.References.Any(r => r.TargetEntry != null &&
      r.TargetEntry.MetaData.IsOwned() && 
      r.TargetEntry.State == EntityState.Added && 
      r.TargetEntry.State == EntityState.Modified)

然后在EntityState.Unchanged的情况下调用它

if (entry.HasChangedOwnedEntities())
{
   entry.Entity.LastModidfiedBy = userId;
   entry.Entity.LastModidfied = _datetime.Now;
}

相关问题