实体框架在更新时删除对象

a2r*_*n44 1 automapper entity-framework-core

我遇到一个问题,实体框架(核心)在更新时删除对象。我认为这与Automapper(将DTO资源映射到对象)有关。我有其他对象以与该对象完全相同的方式映射,并且更新工作得很好。

public async Task<IActionResult> UpdateFeedback(Guid Id, [FromBody] FeedbackResource feedbackResource)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState);
    //removing or else get a tracking error with EF
    feedbackResource.FeedbackType = null;
    var feedback = await feedbackRepository.GetFeedback(Id);

    if (feedback == null)
        return NotFound();

    //if I use this line to map, EF will delete the object upon save.  

    mapper.Map<FeedbackResource, Feedback>(feedbackResource, feedback);

    // if I map manually, i get no error
    //feedback.Title = feedbackResource.Title;
    //feedback.Details = feedbackResource.Details;
    //feedback.IsGoodFeedback = feedbackResource.IsGoodFeedback;
    //feedback.IsReviewed = feedbackResource.IsReviewed;
    //feedback.FeedbackTypeId = feedbackResource.FeedbackTypeId;

    //if(feedbackResource.IsReviewed){
    //    feedback.ReviewDate = DateTime.Now;
    //    feedback.ReviewedBy = UserId;
    //} else {
    //    feedback.ReviewDate = null;
    //    feedback.ReviewedBy = null;
    //}

    await uow.CompleteAsync();

    return Accepted(feedback); 
}
Run Code Online (Sandbox Code Playgroud)

我不知道要在这里解决什么问题,并且在任何谷歌搜索上都看不到这个问题。

Сер*_*ков 5

我面临着类似的情况(ef core 1.1)。我假设你的问题与我的类似。

这里也描述了类似的问题

我有以下型号:

1) ApplicatonUser - 来自 EF 的标准用户

2) AnyDAL - 数据库中的任何类,与用户有链接

 public class AnyDAL
 {
    public long Id { get; set; }

    public long UserId { get; set; }
    public ApplicationUser User { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

3) AnyDTO - 来自浏览器端的模型。像你的[FromBody] FeedbackResource feedbackResource

public class AnyDTO
{
    public long Id { get; set; }

    public long UserId { get; set; }

    /// It is root of all evil. See below.
    /// And yes, it is bad practice.
    public ApplicationUser User { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

设想:

1)得到AnyDAL从数据库中获取;

2)使用AutoMapperAnyDTO进行映射AnyDAL_mapper.Map(DTO, DAL)映射;

3)保存更改()

在一种情况下,SaveChanges()导致删除,在另一种情况下导致更新。

我们应该知道的是:就我而言,财产AnyDTO.User始终是null在反序列化之后。

删除还是更新的选择取决于属性的值AnyDAL.User映射之前属性的值:

1)AnyDAL.User为 null - 我们得到更新。

2)AnyDAL.User不为空 - 我们得到删除。

换句话说。如果属性AnyDAL.User从某个值更改为 null - 实体将被删除。尽管事实上AnyDAL.UserId仍然如此。

有两种方法可以解决:

1) 移除User财产AnyDTO移除财产;

2)财产AnyDTO.User应该永远有价值。