如何使用 EF Core 中的新值更新导航属性? [英] How to update naviation property with new values in EF Core?

查看:44
本文介绍了如何使用 EF Core 中的新值更新导航属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以...我有一个简单的 Product 模型:

Soo... I have this simple model for Product:

public class Product {
    public int Id { get; set; }

    // Other things

    public ICollection<ProductAttribute> ProductAttributes { get; set; }
}

ProductAttributesProductIdName 作为多字段键.

And ProductAttributes with ProductId and Name as multifield keys.

public class ProductAttribute {
    public int? ProductId { get; set; } // Key
    public ProductAttributeName? Name { get; set; } // Key
    public string Value { get; set; }
}

在我的 WebAPI 项目中,我有这个方法:

And in my WebAPI project I have this method:

public async Task<IActionResult> Patch(Product product) {
    var productExist = await _context.Products.AnyAsync(a => a.Id == product.Id);
    if (!productExist) return NotFound(product.Id);
    _context.Products.Update(product);
    await _context.SaveChangesAsync();
    return Ok();
}

并且我假设如果有人在 productAttributes 中使用不同的数据发送我的 JSON,我应该将值切换到完全覆盖的新值或删除旧值.就像这个例子

And I assume that if someone sends my JSON with different data in productAttributes I should switch values to the new ones completely overriding or deleting old values. Like in this example

OldProduct
* Name
* ProductAttributes:
    * Value 1
    * Value 2

NewProduct
* Name
* ProductAttributes:
    * Value 2
    * Value 3

所以 Value1 应该被删除,而 Value3 应该被添加.但是,我在 SaveChangesAsync() 上遇到了异常:

So Value1 should be deleted and Value3 should be added. But instead, I'm getting an exception on SaveChangesAsync():

System.ArgumentException: 'An item with the same key has already been added. Key: System.Object[]'

我猜可能是因为它正在尝试添加 Value2,但它已经存在.

I guess it's probably because it's trying to add Value2, but it already exists.

我应该如何正确更新导航属性?

How should I properly update the naviagation property?

@更新

感谢@cjens19,我只是更改了更新方法并使用了 Automapper:

Thanks to @cjens19 I just change update method and used Automapper:

public async Task<IActionResult> Patch(Product product) {
    var productFromDb = await _context.Products.Include(p => p.ProductAttributes).SingleOrDefaultAsync(product1 => product1.Id == product.Id);
    if (productFromDb == null) return NotFound(product.Id);
    Mapper.Map(product, productFromDb);
    await _context.SaveChangesAsync();
    return Ok();
}

推荐答案

你在做什么//... 检查模型是否存在代码?

What are you doing in the // ... Checking if model exist code?

您应该使用以下内容从上下文中检索现有的 Product 实体:

You should be retrieving the existing Product entity out of the context with something like:

var entity = _context.Products.SingleOrDefault(p => p.Id == product.Id);

然后,如果 entity 不为 null,您可以使用 Product 参数传入的值设置他的属性.

Then, if entity is not null, you can set his properties with the values passed in with the Product param.

最后,您将调用更新和保存.这不应该给您任何 ef 核心错误.

Lastly, you will call Update and Save. This shouldn't give you any ef core errors.

这篇关于如何使用 EF Core 中的新值更新导航属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆