实体框架查找表更新/创建

时间:2015-04-21 14:30:41

标签: c# entity-framework

我有这个创建方法:

[HttpPost]
[Route("")]
/// <summary>
/// Create a team
/// </summary>
/// <param name="model">The team model</param>
/// <returns>The modified team model</returns>
public async Task<IHttpActionResult> Create(TeamBindingViewModel model)
{

    // If our model is invalid, return the errors
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    // Get all our colours
    var colours = await this.colourService.GetAllAsync();

    // Create our new model
    var team = new Team()
    {
        Name = model.Name,
        Sport = model.Sport
    };

    // For each colour, Add to our team
    team.Colours = colours.Where(m => model.Colours.Any(c => c.Id == m.Id)).ToList();

    // Create our team
    this.service.Create(team);

    // Save our changes
    await this.unitOfWork.SaveChangesAsync();

    // Assign our Id to our model
    model.Id = team.Id;

    // Return Ok
    return Ok(model);
}

如您所见,当创建团队时,我需要将颜色添加到查找表中。为此,我从数据库中获取颜色,然后按照作为模型一部分传递的颜色对其进行过滤。

告诉Entity Framework这些 Colors 不是新实体,所以它只是在查找表中创建一个引用,而不是创建新的 Colors

现在我想为更新方法做同样的事情。

我试过了:

[HttpPut]
[Route("")]
/// <summary>
/// Update a team
/// </summary>
/// <param name="model">The team model</param>
/// <returns>The modified team model</returns>
public async Task<IHttpActionResult> Update(TeamBindingViewModel model)
{

    // If our model is invalid, return the errors
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    // Get our current team
    var team = await this.service.GetAsync(model.Id, "Colours");

    // Get all our colours
    var colours = await this.colourService.GetAllAsync();

    // Make changes to our team
    team.Name = model.Name;
    team.Sport = model.Sport;

    // For each colour in our team colours but not in our model colours, remove
    foreach (var colour in team.Colours)
        if (!model.Colours.Any(c => c.Id == colour.Id))
            team.Colours.Remove(colour);

    // For each colour that has to be added, add to our team colours
    if (model.Colours != null)
        foreach (var colour in model.Colours)
            if (!team.Colours.Any(c => c.Id == colour.Id))
                team.Colours.Add(colours.Where(m => m.Id == colour.Id).SingleOrDefault());

    // Update the team
    this.service.Update(team);

    // Save our changes
    await this.unitOfWork.SaveChangesAsync();

    // Return Ok
    return Ok(model);
}

但它没有用。我收到一条错误说明:

  
    

收藏被修改;枚举操作可能无法执行。

  

我知道它正在谈论色彩,但我不知道如何绕过它。

也许有人遇到过类似的问题并设法修复它?

3 个答案:

答案 0 :(得分:1)

这里的问题是你正在改变你正在迭代的集合。

如果要从集合中删除(或添加)项目,则必须分两步执行:

  1. 选择要删除的对象
  2. 删除对象
  3. 如果您的收藏是一个列表,您可以使用List.RemoveAll方法

答案 1 :(得分:1)

您不能迭代收集并同时更改它。如果您确实想要这样做,则必须将所有值存储到某些未修改的位置。最简单的方法是在迭代之前对集合使用ToArray()ToList()

...
// For each colour in our team colours but not in our model colours, remove
foreach (var colour in team.Colours.ToList()) // <<== note change here
    if (!model.Colours.Any(c => c.Id == colour.Id))
        team.Colours.Remove(colour);

// For each colour that has to be added, add to our team colours
if (model.Colours != null)
    foreach (var colour in model.Colours.ToList()) // <<== note change here
        if (!team.Colours.Any(c => c.Id == colour.Id))
            team.Colours.Add(colours.Where(m => m.Id == colour.Id).SingleOrDefault());
...

答案 2 :(得分:-1)

好的,所以在这里的2条评论之后做了一些搜索我想出了这个:

// Loop through our colours and remove the ones that are not in our new colour list
for (var i = 0; i < team.Colours.Count; i++)
    if (!model.Colours.Any(c => c.Id == team.Colours[i].Id))
        team.Colours.RemoveAt(i);

完美无缺。

相关问题