如何在保持实体框架跟踪的同时更新导航集合属性?
域:
public class BuyLink
{
public int Id { get; set; }
string _buyLinkUrl;
public string BuyLinkUrl
{
get
{ return _buyLinkUrl; }
set
{
if (!string.IsNullOrWhiteSpace(value))
_buyLinkUrl = value;
}
}
}
DTO:
public class BuyLinkDto
{
public int Id { get; set; }
public string BuyLinkUrl { get; set; }
}
控制器:
例如,_songService.GetSong(editSongDto.Song.Id).BuyLinks
确实通过跟踪获取当前的buyLinks,但是,如何使用用户提供的editSongDto.BuyLinks编辑更新此集合,而不会丢失此跟踪更改?
[HttpPost]
public ActionResult RequestEdit(EditSongDto editSongDto)
{
//Doesn't work well because entity Framework doesn't track with this assignment so it adds to the database instead of updating.
var buyLinks = _songService.GetSong(editSongDto.Song.Id).BuyLinks = editSongDto.BuyLinkDtos.Select(x => new BuyLink { BuyLinkUrl = x.BuyLinkUrl }).ToList();
_songService.Edit(_songService.GetSong(editSongDto.Song.Id), editSongDto.AudioName, editSongDto.ArtistName, buyLinks);
return View("Index");
}
服务:
public void Edit(Song song, string audioName, string artistName, IEnumerable<BuyLink> buyLinks)
{
song.AudioName = audioName;
song.ArtistName = artistName;
song.BuyLinks = buyLinks?.ToList();
_repository.Edit(song);
}
回购:
public virtual void Edit(T entity)
{
_context.Entry(entity).State = EntityState.Modified;
_context.SaveChanges();
}
答案 0 :(得分:1)
更新实体时,应始终使用数据库中的新实例,而不是创建新实例并尝试使用该实例覆盖现有实例。换句话说:
var song = _songService.GetSong(editSongDto.Song.Id);
var buyLinks = song.BuyLinks.ToList();
...
foreach (var buyLinkDto in editSongDto.BuyLinkDtos)
{
var buyLink = buyLinks.SingleOrDefault(m => m.Id != 0 && m.Id == buyLinkDto.Id);
// New BuyLink
if (buyLink == null)
{
buyLink = new BuyLink { BuyLinkUrl = buyLinkDto.BuyLinkUrl };
song.BuyLinks.Add(buyLink);
}
// Existing BuyLink
else
{
buyLink.BuyLinkUrl = buyLinkDto.BuyLinkUrl;
}
}
现在,实体框架确切地知道发生了什么,并将适当地插入/更新。