首页 > 解决方案 > 保存多对多关系 Entity Framework Core 2.2

问题描述

我知道这个问题已被多次问过,只需简单搜索这篇文章的标题即可证明这一点,但我似乎无法找到解决问题的方法。这里是:

我有以下课程:

public class Assessor : IEntity
{
    public int Id { get; set; }
    public int RegionId { get; set; }
    public string Initials { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }

    public virtual Region Region { get; set; }
    public virtual ICollection<AssessorProductRange> ProductRange {get;set;}
    public virtual ICollection<AssessorAreaRange> AreaRange { get; set; }
}

public class Product : IEntity
{
    public int Id { get; set; }
    public string ProductName { get; set; }
    public string ProductType { get; set; }
    public int CreatedBy { get; set; }
    public DateTime CreatedDate { get; set; }
    public int? UpdatedBy { get; set; }
    public DateTime? UpdatedDate { get; set; }
    public bool IsArchived { get; set; }

    [IgnoreDataMember]
    public virtual ICollection<AssessorProductRange> AssessorProductRange { get; set; }
}

public class AssessorProductRange
{
    public int? AssessorId { get; set; }
    public Assessor Assessor { get; set; }
    public int? ProductId { get; set; }
    public Product Product { get; set; }
}

我也有以下配置(多对多)

public class AssessorProductRangeConfiguration : IEntityTypeConfiguration<AssessorProductRange>
{
    public void Configure(EntityTypeBuilder<AssessorProductRange> builder)
    {
        builder.HasKey(k => new { k.AssessorId, k.ProductId });

        builder.HasOne(o => o.Assessor)
            .WithMany(m => m.ProductRange)
            .HasForeignKey(f => f.AssessorId)
            .OnDelete(DeleteBehavior.Cascade);

        builder.HasOne(o => o.Product)
            .WithMany(m => m.AssessorProductRange)
            .HasForeignKey(f => f.ProductId)
            .OnDelete(DeleteBehavior.Restrict);
    }
}

该类Assessor包含有关评估员的一些信息。该类Product包含有关系统中可用的产品/服务的一些信息。是和之间的AssessorProductRange连接表。AssessorProduct

我的网站中有一个部分,您可以在其中添加/编辑评估员,以及添加/删除该评估员提供的产品。这是一个截图供参考。

在此处输入图像描述

当我添加评估者时, 和 之间的链接AssessorProduct预期工作,并且相关数据按预期保存到每个单独的表中。

当我编辑一个 Assessor 时,假设我删除(取消勾选)一个复选框,并保存该 Assessor,未选中的产品不会从AssessorProductRange表中删除。请注意,Assessor对象本身的所有属性,例如 Initials 等都会正确更新。

这是我的Update方法,具有相应的功能。

我不能为我的生活弄清楚为什么?任何帮助,将不胜感激。

public async Task<bool> UpdateAssessorAsync(Assessor assessor)
    {
        try
        {
            //this._repo.AttachEntity<Assessor>(assessor);
            this._repo.ModifyState<Assessor>(assessor, Microsoft.EntityFrameworkCore.EntityState.Modified);
            this._repo.ModifyState<AssessorAreaRange>(assessor.AreaRange, Microsoft.EntityFrameworkCore.EntityState.Modified);
            this._repo.ModifyState<AssessorProductRange>(assessor.ProductRange, Microsoft.EntityFrameworkCore.EntityState.Modified);
            return await this._repo.SaveAsync() > 0 ? true : false;
        }
        catch (Exception)
        {
            //log
            throw;
        }
    }

public void ModifyState<TEntity>(TEntity entity, EntityState state) where TEntity : class, IEntity
    {
        Context.Entry(entity).State = state;
    }

    public void ModifyState<TEntity>(ICollection<TEntity> entities, EntityState state) where TEntity : class
    {
        foreach (TEntity entity in entities)
            Context.Entry(entity).State = state;
    }

标签: c#asp.net-coreentity-framework-core

解决方案


您需要AssessorProductRange使用当前数据删除现有记录AssessorId并使用新数据进行更新:

var list = _context.AssessorProductRange.Where(s => s.AssessorId == Assessor.Id).ToList();
_context.AssessorProductRange.RemoveRange(list);
_context.Update(accessor);
await _context.SaveChangesAsync();

推荐阅读