导航属性不会重置为空

时间:2020-08-31 12:36:07

标签: c# entity-framework-core

我有一个简单的应用程序,它可以从以下批次的已售票中注册collection的款项 驱动程序(领域专家称为settlements)。我尝试使用DDD方法和EF Core来处理这个小型应用程序(称其为在DDD中使用EF Core的游乐场)。我在SQL Server中基本上有3个表(简化为绝对最小值):

Table: Collection
-------------+---------
   Column    | Type    
-------------+---------
CollectionId | int (PK)    
IsCancelled  | bit     
Table: Settlement
-------------+---------
   Column    | Type    
-------------+---------
SettlementId | int (PK)
CollectionId | int (FK)
Number       | int     
Table: CollectionSettlementJoin
-------------+---------
   Column    | Type    
-------------+---------
SettlementId | int (PK)(FK)
CollectionId | int (PK)(FK)

我知道似乎有一个冗余的联接表(因为我在CollectionId表上有Settlement),但这似乎是设计要求,我将在稍后解释。因此,每个collection至少具有1个或更多settlements。我有2个实际上与表相对应的域实体-我的聚合根Collection并附加到包含Settlements实体列表的Settlement属性中。 额外的表用于审计目的,因为实际上并不真正参与该域。它由Settlement.CollectionId更新时的触发器填充(对于非null)。每个collection可以在创建后的5分钟内被创建者取消,也可以由超级用户随时取消。取消collection时,我想将Settlement.CollectionId重置为null(发生这种情况时,CollectionSettlementJoin中的数据保持不变,我总能取回取消的结算)。 / p>

创建collection时,我当前的设置工作正常。所选的settlements已添加,保存并成功保存在我的数据库中。当我想取消收藏时,问题就开始了。我从数据库中获取了带有附件collection的{​​{1}}。但是,当我从聚合根中删除settlements时,settlements不会保留更改(不会将dbContext.SaveChanges()设置为Settlement.CollectionId)。

这是我的设置:

null
public class Collection : EntityBase, IAggregateRoot
{
    private Collection() { }
    public Collection(List<Settlement> settlements)
        {
            _settlements = settlements;
        }
    private bool _isCancelled;
    public bool IsCancelled => _isCancelled;

    private List<Settlement> _settlements;
    public IReadOnlyCollection<Settlement> Settlements => _settlements.AsReadOnly();

    public void CancelCollection()
    {
        if (_isCancelled != true)
        {
            _isCancelled = true;
            _settlements.Clear();
        }
    }
}
public class Settlement : EntityBase
{
    private Settlement() { }
    public Collection? Collection { get;set; }
    public int? CollectionId { get; internal set; }
}
public class CollectionEntityTypeConfiguration : IEntityTypeConfiguration<Collection>
{
    public void Configure(EntityTypeBuilder<Collection> builder)
    {
        builder.ToTable("Collection");
        builder.HasKey(s => s.Id);
        builder.Property(s => s.Id).HasColumnName("CollectionId").UseIdentityColumn();
        builder.Property(s => s.IsCancelled).HasDefaultValueSql("(0)");
        builder.HasMany(s => s.Settlements)
            .WithOne(c => c.Collection)
            .HasForeignKey(s => s.CollectionId);
    }
}

上下文(此处不多)

public class SettlementEntityTypeConfiguration : IEntityTypeConfiguration<Settlement>
{
    public void Configure(EntityTypeBuilder<Settlement> builder)
    {            
        builder.ToTable("Settlement");
        builder.HasKey(s => s.Id);
        builder.Property(s => s.Id).HasColumnName("SettlementId").ValueGeneratedNever();
        builder.Property(s => s.CollectionId);
        builder.HasOne(s => s.Collection)
            .WithMany(c => c.Settlements)
            .HasForeignKey(s => s.CollectionId);                
    }
}

最后是我的命令:

public class SettlementCollectionContext: DbContext
{        
    public SettlementCollectionContext(
        DbContextOptions<SettlementCollectionContext> options) : base(options)
    {
        ChangeTracker.StateChanged += ChangeTracker_StateChanged;
    }

    private void ChangeTracker_StateChanged(object sender, EntityStateChangedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"Entity {e.Entry.Entity.GetType().Name} has changed.");
    }

    public DbSet<Collection> Collections { get; set; }
    public DbSet<Settlement> Settlements { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new SettlementEntityTypeConfiguration());
        modelBuilder.ApplyConfiguration(new CollectionEntityTypeConfiguration());
    }
}

我知道var collection = await _dbContext.Collections .Include(c => c.Settlements) .Where(c => c.Id == collectionId) .SingleOrDefaultAsync(); if (!collection!.IsCancelled) { collection.CancelCollection(); } _dbContext.Update(collection); //without this the change tracker does not register the change _dbContext.SaveChanges(); 注册了此更改,因为我在上下文中向ChangeTracker添加了一个偶数处理程序,并且在调试过程中我注意到它注册了ChangeTracker.StateChanged已更改(尽管collection)。我还尝试通过settlement方法将Settlement.CollectionId属性重置为null,但这也没有帮助。我一定很想念东西。

1 个答案:

答案 0 :(得分:1)

因此最后,设置没有问题。实际上,我的工作单元存在问题,因为它保存了错误的上下文,因此很明显,这些更改永远不会持久。

相关问题