在EntityFramework核心中创建包含现有子项的父项

时间:2017-05-26 10:03:11

标签: asp.net-core entity-framework-core

我正在构建Web API并有两个模型:任务和功能:

{

    "to": "cQeIXyI-3B4:APA91bFiycO1OWFsV_HSp0_rV5hdYl5HCRCfjkTTbiW5Isnlg_b-97nN5oc5LkZ82gkKOSL8oRRhDAY_y3ql3sbjTyKHtzAxrucmukjBOf3zWSnY6LI_3IF74oXwJzxMiELNCmFqYHuE",

    "priority": "high",
    "mutable-content" : 1,
    "content_available" : true,
    "data":{
    "name":"a name",
    "title":"A Title",
    "test":"true"
    }

}

我首先创建任务,然后创建一个结合了其中几个的功能。任务创建成功,但在使用现有任务创建功能时,我的控制器会抛出一个错误,说任务已经存在:

我的FeatureController有以下方法:

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()
    {

    }

}

如何告诉EF核心传入功能是否具有已存在的任务,只需更新引用而不是创建新引用?

我的背景:

//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);
} 

回购:

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; }

}

1 个答案:

答案 0 :(得分:0)

在使用未从EF加载的模型调用DBSet上的Add时,它认为它是未跟踪的并且始终认为它是新的。

相反,您需要从dbcontext加载现有记录,并将传递到API的数据中的属性映射到现有记录。通常,这是从参数对象到域的手动映射。然后,如果您返回一个对象,则会将该新域对象映射到DTO。您可以使用AutoMapper等服务将域映射到DTO。完成映射后,只需要调用SaveChanges。

一般来说,加载记录和映射字段对于API的安全性是一件好事。您不希望假设传入的数据是原始的和诚实的。当您给调用代码访问实体的所有属性时,您可能不希望它们更改所有字段,并且其中一些字段可能是敏感的。