在 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
DestinationId
和 SiteCodeID
是外键。 DestinationId
是指Destination
table(ID
),SiteCodeId
是指SiteCode
table(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>();
}
如何在 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 |
DestinationId
和 SiteCodeID
是外键。 DestinationId
是指Destination
table(ID
),SiteCodeId
是指SiteCode
table(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>();
}