How to update naviation property with new values in EF Core?

ε祈祈猫儿з 提交于 2020-02-06 19:02:31

问题


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

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

    // Other things

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

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

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

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

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[]'

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

How should I properly update the naviagation property?

@Update

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

回答1:


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

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

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

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



来源:https://stackoverflow.com/questions/57291585/how-to-update-naviation-property-with-new-values-in-ef-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!