【问题标题】:Entity Framework deleting object upon Update实体框架在更新时删除对象
【发布时间】:2018-05-19 19:00:48
【问题描述】:

我遇到了一个问题,即 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); 
}

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

【问题讨论】:

  • 您应该首先在代码中添加一个断点,以便您可以检查映射操作的结果,并确保 FeedbackResource 的所有属性都已绑定并按预期显示。

标签: automapper entity-framework-core


【解决方案1】:

我也遇到过类似的情况(ef core 1.1)。我会假设你的问题和我的类似。

Also a similar problem is described here

我有以下型号:

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

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

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

    public long UserId { get; set; }
    public ApplicationUser User { get; set; }
}

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

场景:

1) 从数据库中获取AnyDAL

2) 使用 AutoMapper _mapper.Map(DTO, DAL)AnyDTO 映射到 AnyDAL

3) SaveChanges()

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

我们应该知道:在我的例子中,属性AnyDTO.User 在反序列化后总是null

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

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

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

换句话说。如果属性 AnyDAL.User 从某个值更改为 null - 实体将被删除。尽管AnyDAL.UserId 保持不变。

有两种方法可以解决:

1) 从AnyDTO 中删除属性User

2) 属性AnyDTO.User 应该始终具有值。

【讨论】:

  • 如果您有类似的问题,请不要使用 Answers(!) 部分,而是开始一个新问题。
  • 我描述了我对类似问题的解决方案,并指出了问题的确切原因。
  • 好吧,您只描述了您自己问题的原因(“AnyDAL.User 从某个值更改为 null”)尚不清楚您是如何解决的。发布所有代码确实没有多大帮助。你可以简单地问:也许引用设置为null?但是您必须等到可以发表评论。
  • 是的,起初我想发表评论,但我不能这样做,因为新手。
  • 再次:请等到可以。尝试通过发布有效答案或好问题来获得声誉。信誉阈值的存在是有原因的,答案部分不是替代方案。顺便说一句,您想贡献真是太好了,而且理解网站礼仪需要一段时间。
【解决方案2】:

这有点旧,但我遇到了与 EF Core 2.2 相同的问题,并且基于此 EntityFrameworkCore 在 3.0 中仍然是一个问题

问题似乎是导航属性为空导致实体被删除。

我可以通过配置延迟加载来解决

安装这个包

Microsoft.EntityFrameworkCore.Proxies

在配置中开启延迟加载

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseLazyLoadingProxies();

【讨论】:

    【解决方案3】:

    对我来说,这个问题最终是由自动映射器和 EntityFramework 之间的交互引起的。 Automapper creating new instance rather than map properties

    对此进行了很好的描述

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-05
      • 2018-04-06
      • 2011-05-08
      • 1970-01-01
      相关资源
      最近更新 更多