在 Entity Framework 核心中更新多个值

Update with Multiple Values in Entity Framework Core

如何在 Entity Frame Work Core 中使用多个值进行更新。

这是我的table

目的地 ID 站点代码 ID
1 1
2 1
3 2
4 1
5 4

我需要这样更新

目的地 ID 站点代码 ID
1 1
2 1
3 2
4 1
4 2
4 3
5 5
5 2

DestinationIdSiteCodeID 是外键。 DestinationId是指Destinationtable(ID),SiteCodeId是指SiteCodetable(ID).

这是Destination.cs

public class Destination
{
    [Key]
    public int Id { get; private set; }

    public List<DealDestination> DealDestinations { get; set; }
    public List<SiteDestination> SiteDestinations { get; set; }

    [NotMapped]
    public List<int> SiteCode { get; set; }
}

public class SiteDestination
{
    public int DestinationId { get; set; }
    public int SiteCodeId { get; set; }

    public SiteCode SiteCode { get; set; }

    public Destination Destination { get; set; }
}

我确实喜欢这样,我删除了该数据并添加了新数据。但这是错误的。我要更新了。

public async Task<Destination> Update(Destination destination)
{
        _catalogDbContext.Destinations.Update(destination);

        var siteDestination = new SiteDestination
        {
        };

        var oldSiteDestinations = await _catalogDbContext.SiteDestinations.Where(i => i.DestinationId == destination.Id).ToListAsync();
        _catalogDbContext.RemoveRange(oldSiteDestinations);

        foreach (var Id in destination.SiteCode)
        {
            var siteCodeId = _catalogDbContext.SiteCodes.Include(i => i.Id);

            siteDestination.SiteCodeId = Id;
            siteDestination.DestinationId = destination.Id;

            await _catalogDbContext.SiteDestinations.AddAsync(siteDestination);
            await _catalogDbContext.SaveChangesAsync(true);

        return destination;
}

如何更新多个值?给我一些例子或想法。

更新

这个问题引发了其他问题。为了解决这个问题,让我们从控制器一直到数据库。

问题是关于发布 JSON 这样的:

{"id": 1,  "siteCode": [1,2,9] }

并在往返 db 后收到完全相同的 JSON。

我们不使用 EF 实体模型作为请求模型,而是创建一个如下所示的视图模型并稍微清理一下实体 classes(显示在最后):

public class DestinationVm
{
    [Required]
    public int? Id { get; set; }
    
    [Required]
    public ICollection<int> SiteCode { get; set; }
}

测试期间使用的控制器。为简单起见,业务逻辑包含在控制器 class 中。 Put方法简单,不照书本

[ApiController]
[Route("api/[controller]")]
public class DestinationController : ControllerBase
{
    private readonly SchoolContext _catalogDbContext;

    public DestinationController(SchoolContext catalogDbContext)
    {
        _catalogDbContext = catalogDbContext;
    }

    [HttpPut]
    public ActionResult<DestinationVm> PutDestination([FromBody] DestinationVm viewModel)
    {
        var updatedEntity = Update(viewModel);

        var returnModel = new DestinationVm
        {
            Id = updatedEntity.Id,
            SiteCode = updatedEntity.SiteDestinations
                .Select(it => it.SiteCodeId)
                .ToArray()
        };
        return Ok(returnModel);
    }

    private Destination Update(DestinationVm viewModel)
    {
        var destinationFromDb = _catalogDbContext.Destinations
            .Include(x => x.SiteDestinations)
            .Single(it => it.Id == viewModel.Id);

        // delete children not present in view model
        foreach (var siteDestination in destinationFromDb.SiteDestinations
            .Where(it => viewModel.SiteCode
                .All(x => x != it.SiteCodeId)).ToList())
        {
            destinationFromDb.SiteDestinations.Remove(siteDestination);
        }

        // insert children not present in db
        foreach (var currentSiteCode in viewModel.SiteCode
            .Where(it => destinationFromDb.SiteDestinations
                .All(x => x.SiteCodeId != it)))
        {
            destinationFromDb.SiteDestinations.Add(new SiteDestination
            {
                SiteCodeId = currentSiteCode
            });
        }
        
        _catalogDbContext.SaveChanges();
        return destinationFromDb;
    }
}

多对多关系定义如下(必填,因为问题是关于 Core 3.1):

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<SiteDestination>()
        .HasKey(e => new {e.DestinationId, e.SiteCodeId});

    modelBuilder.Entity<SiteDestination>()
        .HasOne(e => e.Destination)
        .WithMany(p => p.SiteDestinations);

    modelBuilder.Entity<SiteDestination>()
        .HasOne(e => e.SiteCode)
        .WithMany(p => p.SiteDestinations);
}

测试期间使用的模型 class:

public class SiteCode
{
    public int Id { get; set; }

    public ICollection<SiteDestination> SiteDestinations { get; } = new List<SiteDestination>();

    // some more properties here
}

public class SiteDestination
{
    public int DestinationId { get; set; }
    public Destination Destination { get; set; }

    public int SiteCodeId { get; set; }
    public SiteCode SiteCode { get; set; }
}

public class Destination
{
    public int Id { get; set; }

    public ICollection<SiteDestination> SiteDestinations { get; } = new List<SiteDestination>();
}