在EntityFramework核心中創建包含現有子項的父項

asp.net-core entity-framework-core

我正在構建一個Web API並有兩個模型:任務和功能:

public class Feature
{
    [Key]
    public long FeatureId { get; set; }
    public string Analyst_comment { get; set; }

    public virtual ICollection<User_Task> Tasks { get; set; }

    public Feature()
    {

    }
}

public class User_Task
{
    [Key]
    public long TaskId { get; set; }
    public string What { get; set; }

    [ForeignKey("FeatureId")]
    public long? FeatureId { get; set; }


    public User_Task()
    {

    }

}

我首先創建任務,然後創建一個結合了其中幾個的功能。任務創建成功,但在使用現有任務創建功能時,我的控制器會拋出一個錯誤,說該任務已經存在:

我的FeatureController有以下方法:

//Create
[HttpPost]
public IActionResult Create([FromBody] Feature item)
{
    if (item == null)
    {
        return BadRequest();
    }

    ** It basically expects that I am creating a Feature with brand new tasks, so I guess I will need some logic here to tell EF Core that incoming tasks with this feature already exist **

    _featureRepository.Add(item);

    return CreatedAtRoute("GetFeature", new { id = item.FeatureId }, item);
} 

如何告訴EF核心傳入的功能有已存在的任務,它只需要更新引用而不是創建新的引用?

我的背景:

public class WebAPIDataContext : DbContext
{
    public WebAPIDataContext(DbContextOptions<WebAPIDataContext> options)
        : base(options)
    {
    }

    public DbSet<User_Task> User_Tasks { get; set; }
    public DbSet<Feature> Features { get; set; }

}

回購:

public void Add(Feature item)
{
    _context.Features.Add(item);
    _context.SaveChanges();
}

熱門答案

當使用未從EF加載的模型在DBSet上調用Add時,它認為它是未跟踪的並且始終假定它是新的。

相反,您需要從dbcontext加載現有記錄,並將傳遞到API的數據中的屬性映射到現有記錄。通常,這是從參數對像到域的手動映射。然後,如果您返回一個對象,則會將該新域對象映射到DTO。您可以使用AutoMapper等服務將域映射到DTO。完成映射後,只需調用SaveChanges即可。

一般來說,加載記錄和映射字段對於API的安全性是一件好事。您不希望假設傳入的數據是原始的和誠實的。當您給調用代碼訪問實體的所有屬性時,您可能不希望它們更改所有字段,並且其中一些字段可能是敏感的。



Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow