首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用实体框架核心更新相关数据

使用实体框架核心更新相关数据
EN

Stack Overflow用户
提问于 2017-03-11 20:44:42
回答 2查看 13.9K关注 0票数 16

我正在建立一个简单的webapi与实体框架核心。我使用模型和视图模型来管理客户端实际接收的数据。下面是我创建的模型和视图模型:

代码语言:javascript
复制
public class Team : BaseEntity
{
    [Key]
    public int TeamId { get; set; }
    [Required]
    public string TeamName { get; set; }
    public List<TeamAgent> TeamAgents { get; set; }
}

public class TeamViewModel
{
    [Required]
    public int TeamId { get; set; }
    [Required]
    public string TeamName { get; set; }
    [DataType(DataType.Date)]
    public DateTime DateCreated { get; set; }
    [DataType(DataType.Date)]
    public DateTime DateModified { get; set; }
    public List<TeamAgent> TeamAgents { get; set; }
}

public class TeamAgent : BaseEntity
{
    [Key]
    public int TeamAgentId { get; set; }
    [ForeignKey("Agent")]
    public int AgentId { get; set; }
    [JsonIgnore]
    public virtual Agent Agent { get; set; }
    [ForeignKey("Team")]
    public int TeamId { get; set; }
    [JsonIgnore]
    public virtual Team Team { get; set; }
    [Required]
    public string Token { get; set; }
}

public class TeamAgentViewModel
{
    [Required]
    public virtual AgentViewModel Agent { get; set; }
    [Required]
    public string Token { get; set; }
}

现在为了更新,我在我的控制器中创建了一个Update方法:

代码语言:javascript
复制
[HttpPut("{id}")]
public async Task<IActionResult> Update(int id, [FromBody]TeamViewModel teamVM)
{
    if (ModelState.IsValid)
    {
        var team = await _context.Teams
                            .Include(t => t.TeamAgents)
                            .SingleOrDefaultAsync(c => c.TeamId == id);

        team.TeamName = teamVM.TeamName;

        // HOW TO HANDLE IF SOME TEAMAGENTS GOT ADDED OR REMOVED???

        _context.Teams.Update(team);
        await _context.SaveChangesAsync();

        return new NoContentResult();
    }
    return BadRequest(ModelState);
}

我陷入了如何更新连接到团队的TeamAgents的问题。我尝试和工作的一件事是删除所有的TeamAgents,然后在每次团队数据更新时创建新的。下面是操作步骤:

代码语言:javascript
复制
team.TeamAgents.Clear();
await _context.SaveChangesAsync();
team.TeamAgents.AddRange(teamVM.TeamAgents);

_context.Teams.Update(team);
await _context.SaveChangesAsync();

但这显然不是一个很好的方法。使用实体框架核心更新相关项的正确方式是什么?

EN

回答 2

Stack Overflow用户

发布于 2017-11-06 04:03:57

朱莉·勒曼在她2016年4月的文章Handling the State of Disconnected Entities in EF中提到了这一点。如果你还没有看过这篇文章,这篇文章很值得一读。遗憾的是,从EF Core 2.0开始,仍然没有内置的方法来更新对象图。

Julie的文章中提到的方法基本上是通过向对象添加一个属性并将状态发送到客户端来跟踪分离实体的状态。客户端可以修改状态并将其发送回服务器,然后您当然可以使用该信息来执行正确的操作。

在我最近的项目中,我采取了稍微不同的方法,主要是因为到目前为止只有一个需要更新子集合的操作。在我不得不再次这样做的时候,我可能会把Julie的建议放在心上并进行重构。

基本上这只是一个手动的对象图更新,它看起来非常类似于你在EF 6.0中采取的方法。要注意的一件事是,现在使用EF Core,您可以只调用Remove()来传递实体,而不必关心它属于哪个dbSet。

代码语言:javascript
复制
/// <param name="entity"></param>
public override void Update(Group entity) {
    // entity as it currently exists in the db
    var group = DbContext.Groups.Include(c => c.Contacts)
        .FirstOrDefault(g => g.Id == entity.Id);
    // update properties on the parent
    DbContext.Entry(group).CurrentValues.SetValues(entity);
    // remove or update child collection items
    var groupContacts = group.Contacts.ToList();
    foreach (var groupContact in groupContacts) {
        var contact = entity.Contacts.SingleOrDefault(i => i.ContactId == groupContact.ContactId);
        if (contact != null)
            DbContext.Entry(groupContact).CurrentValues.SetValues(contact);
        else
            DbContext.Remove(groupContact);
    }
    // add the new items
    foreach (var contact in entity.Contacts) {
        if (groupContacts.All(i => i.Id != contact.Id)) {
            group.Contacts.Add(contact);
        }
    }
    DbContext.SaveChanges();
}
票数 18
EN

Stack Overflow用户

发布于 2020-12-17 16:59:06

这要归功于@Slauma。

代码语言:javascript
复制
public void Update(UpdateParentModel model)
{
    var existingParent = _dbContext.Parents
        .Where(p => p.Id == model.Id)
        .Include(p => p.Children)
        .SingleOrDefault();

    if (existingParent != null)
    {
        // Update parent
        _dbContext.Entry(existingParent).CurrentValues.SetValues(model);

        // Delete children
        foreach (var existingChild in existingParent.Children.ToList())
        {
            if (!model.Children.Any(c => c.Id == existingChild.Id))
                _dbContext.Children.Remove(existingChild);
        }

        // Update and Insert children
        foreach (var childModel in model.Children)
        {
            var existingChild = existingParent.Children
                .Where(c => c.Id == childModel.Id && c.Id != default(int))
                .SingleOrDefault();

            if (existingChild != null)
                // Update child
                _dbContext.Entry(existingChild).CurrentValues.SetValues(childModel);
            else
            {
                // Insert child
                var newChild = new Child
                {
                    Data = childModel.Data,
                    //...
                };
                existingParent.Children.Add(newChild);
            }
        }

        _dbContext.SaveChanges();
    }
}

来源:

https://stackoverflow.com/a/27177623/3850405

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42735368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档