EntityFramework.Core - 多对多更新

时间:2018-02-14 15:38:40

标签: entity-framework rest asp.net-web-api

我正在尝试更新数据库中的条目。首先,这是我的代码:

饮料

public class Beverage
{
    [Key]
    public int BeverageID { get; set; }

    public string BeverageName { get; set; }

    public HashSet<BeverageAdditive> Additive { get; set; } = new HashSet<BeverageAdditive>();
}

添加剂:

public class Additive : IPickerFriendlyModel, IBeverageType
{
    [Key]
    public int AdditiveID { get; set; }

    public string AdditiveName { get; set; }

    public ICollection<BeverageAdditive> Beverage { get; set; } = new HashSet<BeverageAdditive>();
}

BeverageAdditive:

public class BeverageAdditive
{
    // Is a ForeignKey
    public int BeverageID { get; set; }

    // Is a ForeignKey
    public int AdditiveID { get; set; }

    [JsonIgnore]
    public Beverage Beverage { get; set; }

    [JsonIgnore]
    public Additive Additive { get; set; }
}

控制器:

public class BeverageController : Controller
{
    // PUT: api/Beverage/5
    [HttpPut("{id}")]
    public IActionResult Put(int id, [FromBody]Beverage bev)
    {
        try
        {
            if (bev == null)
            {
                return BadRequest();
            }

            // Get the existing Beverage
            var item = GetByID(bev.BeverageID);
            if (item == null)
            {
                return NotFound();
            }

            // Update the values
            Context.Entry(item).CurrentValues.SetValues(bev);

            // Save the changes
            Context.SaveChanges();

            // Return everything done as expected
            return Ok();
        }
        catch (Exception ex)
        {
            return BadRequest(ex);
        }
    }
}

我将通过Curl称这个Api:

curl -X PUT --header 'Content-Type: application/json-patch+json' --header 'Accept: text/html' -d '{ \ 
"beverageID": 91, \ 
"beverageName": "Test3", \ 
"additive": [ \ 
 { \ 
   "beverageID": 91, \ 
   "additiveID": 4 \ 
 }, \ 
 { \ 
   "beverageID": 91, \ 
   "additiveID": 2 \ 
 } \ 
], \ 
}' 'http://localhost:9001/api/Beverage/91'

问题是,表 BeverageAllergen 没有得到更新(也没有插入新的添加剂),我没有得到异常。价值保持不变。

有谁知道造成这种情况的原因是什么?

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

所以我终于想出它是如何运作的。您必须手动删除并添加Entites,因此工作代码将是这样的:

public class BeverageController : Controller
{
// PUT: api/Beverage/5
[HttpPut("{id}")]
public IActionResult Put(int id, [FromBody]Beverage bev)
{
    try
    {
        if (bev == null)
        {
            return BadRequest();
        }

        // Get the existing Beverage
        var item = GetByID(bev.BeverageID);
        if (item == null)
        {
            return NotFound();
        }

        // Update the values
        Context.Entry(item).CurrentValues.SetValues(bev);

            // ####################################################
            // ######### This is where the magic happens ##########

            // If theres a records that have a 0 as ID, remove them
            bev.Additive.RemoveWhere(add => add.AdditiveID <= 0);

            // Remove the already exising Additives
            RemoveAllAdditives(item);

            // Add the Additives
            for (int i = 0; i < bev.Additive.Count; i++)
            {
                AddAdditive(item, bev.Additive.ElementAt(i).AdditiveID);
            }
            // #####################################################


        // Save the changes
        Context.SaveChanges();

        // Return everything done as expected
        return Ok();
    }
    catch (Exception ex)
    {
        return BadRequest(ex);
    }
}
}
    private void AddAdditive(Beverage item, int additiveID)
    {
        var add = new AdditiveController(Context).GetByID(additiveID);

        if (add == null)
        {
            return;
        }

        var bevAdd = new BeverageAdditive()
        {
            Beverage = item,
            Additive = add
        };
        item.Additive.Add(bevAdd);
    }

    private void RemoveAdditive(Beverage bev, int additiveID)
    {
        var beva = bev.Additive.Where(bevAdd => bevAdd.BeverageID == bev.BeverageID && bevAdd.AdditiveID == additiveID).FirstOrDefault();
        bev.Additive.Remove(beva);
        Context.SaveChanges();
    }

    private void RemoveAllAdditives(Beverage bev)
    {
        for (int n = 0; n < bev.Additive.Count; n++)
        {
            RemoveAdditive(bev, bev.Additive.ElementAt(n).AdditiveID);
            n--;
        }
    }

希望这可以帮助遇到与我一样的问题的人