Entity Framework Core - 如何处理相关实体映射和保存

Posted

技术标签:

【中文标题】Entity Framework Core - 如何处理相关实体映射和保存【英文标题】:Entity Framework Core - How to handle Related Entity Mapping and Saving 【发布时间】:2018-06-07 05:17:35 【问题描述】:

我有两个相关的实体,它们是一对多的关系,如下所示:

class parent
 public string parentNameget;set;
 public virtual ICollection<child> childs  get; set; 


class child
  public string childNameget;set;
  public parent parentget;set;
  ["ForeignKey"]
  public int parentId get; set;

/// View Model
class VMParent
  public string parentNameget;set;
  /// a string array contains child name
  public string[] childlist  get; set; 

假设我的父母目前包含 2 个孩子的名字:(apple, pear),现在我想通过 web api 更新它以包含 3 个孩子 (apple, orange,banana),注意这里 existed child pear is removed 并添加了 2 new child(orange,banana),这里假设 orange 已经存在于 table child 但香蕉不存在,它应该被视为子表的新条目,我可以在字符串数组中获取带有子名的更新模型(["apple", "orange", "banana"])来自 web api body 视图模型,如:

[HttpPut("id")]
public async Task<IActionResult> Update(string name, [FromBody]VMParent VMUpdateParent)

    if (ModelState.IsValid)
    
        var existingParent = await _context.Parents
                            .Include(t => t.childs)
                            .SingleOrDefaultAsync(p => p.parentName == name);

        existingParent.parentName = updateParent.parentName;

        var childsToBeUpdated = updateParent.childList; /// ["apple","orange","banana"]

        /// HOW TO HANDLE or REBUILD the relationship that can
        /// 1) remove child (pear) from existingParent
        /// 2) add child "banana" to Child table
        /// 3) add childs (orange and banana) to existingParent?
        ......

        _context.Parents.Update(existingParent);
        await _context.SaveChangesAsync();

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

Entity Framework Core 中是否有类似 SQL 的“MERGE”语句?我真的很期待更多关于实体框架的实际应用教程......

【问题讨论】:

最好用这种方式写。您将 parentid 列作为外键添加到子表中,然后传递父名称并使用 where 条件(将父 id 与父表连接)从子表更新所有子表到 parentid 设置 null 谢谢!我已经在子表中添加了外键列parentId,但是接下来我该怎么做呢? 您应该将parentid设置为null或从子表中删除条目 为了做到这一点,我想我会做以下步骤:1)从我的“existingParent”实体中,映射一个孩子的名字数组(因为“existingParent”实体将包含一个“孩子" object not just name) 2) 使用映射数组与我的视图模型“VMUpdateParent”子名称数组进行比较,找出需要删除的“pear”和需要删除的“orange,banana”添加 3) 从子表中按名称 equlas "pear" 选择单个子实体,将 "parentId" FK 设置为空 4) 从子表中按名称 "orange/banana" 选择每个子实体,设置 "parentId" FK,对吗? 感觉过程很复杂,有什么有效的方法吗? 【参考方案1】:

我自己想出了一种解决方案,方法是在视图模型 VMUpdateParent 与现有模型 existingParent 之间使用 AutoMapper删除不必要的孩子节点并添加新的子节点。

但是,如果有人有任何改进或更好的解决方案,请随时在这里分享。提前致谢!

【讨论】:

以上是关于Entity Framework Core - 如何处理相关实体映射和保存的主要内容,如果未能解决你的问题,请参考以下文章

Entity Framework Core 忽略 .Include(..) 而没有 .ToList(..) 间接

在 .NET Core 3.1 和 Entity Framework Core 中处理非常大的请求是一个好主意[关闭]

Entity Framework Core 6.0 预览4 性能改进

Entity Framework Core快速开始

Entity Framework Core 快速开始

EF6 System.Data.Entity.Core.EntityKey 在 Entity Framework Core 中的等价物是啥?