C# 实体框架查找表更新/创建
我有一个创建方法:C# 实体框架查找表更新/创建,c#,entity-framework,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&g
[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);
}
[HttpPost]
[路线(“”)
///
///组建一个团队
///
///团队模式
///改进的团队模型
公共异步任务创建(TeamBindingViewModel模型)
{
//如果我们的模型无效,请返回错误
如果(!ModelState.IsValid)
返回请求(ModelState);
//得到我们所有的颜色
var colors=wait this.colorservice.GetAllAsync();
//创建我们的新模型
var团队=新团队()
{
Name=model.Name,
运动型
};
//对于每种颜色,添加到我们的团队中
team.colors=colors.Where(m=>model.colors.Any(c=>c.Id==m.Id)).ToList();
//创建我们的团队
这个。服务。创建(团队);
//保存我们的更改
等待此消息。unitOfWork.SaveChangesSync();
//将我们的Id分配给我们的模型
model.Id=team.Id;
//返回Ok
返回Ok(型号);
}
如您所见,创建团队时,我需要将颜色添加到查找表中。为此,我从数据库中获取颜色,然后根据作为模型一部分传递的颜色对它们进行过滤
这告诉实体框架这些颜色不是新的实体,因此它只是在查找表中创建一个引用,而不是创建新的颜色
现在我想对update方法执行同样的操作
我试过这个:
[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);
}
[HttpPut]
[路线(“”)
///
///更新团队
///
///团队模式
///改进的团队模型
公共异步任务更新(TeamBindingViewModel模型)
{
//如果我们的模型无效,请返回错误
如果(!ModelState.IsValid)
返回请求(ModelState);
//让我们现在的团队
var team=wait this.service.GetAsync(model.Id,“colors”);
//得到我们所有的颜色
var colors=wait this.colorservice.GetAllAsync();
//改变我们的团队
team.Name=model.Name;
team.Sport=model.Sport;
//对于我们团队颜色中的每种颜色,但不是我们的车型颜色,请删除
foreach(团队中的var颜色。颜色)
如果(!model.colors.Any(c=>c.Id==color.Id))
团队。颜色。移除(颜色);
//对于必须添加的每种颜色,请添加到我们的团队颜色中
如果(model.colors!=null)
foreach(型号中的var颜色。颜色)
如果(!team.colors.Any(c=>c.Id==color.Id))
添加(colors.Where(m=>m.Id==color.Id).SingleOrDefault());
//更新团队
本.服务.更新(团队);
//保存我们的更改
等待此消息。unitOfWork.SaveChangesSync();
//返回Ok
返回Ok(型号);
}
但它不起作用。我得到一个错误声明:
收集被修改;枚举操作不能执行
我知道它在谈论颜色,但我不知道如何避开它
也许有人遇到过类似的问题并设法解决了它?这里的问题是您正在更改正在迭代的集合 如果要从集合中删除(或添加)项,必须分两步执行:
如果您的集合是一个列表,则可以使用方法您不能在遍历集合的同时对其进行更改。如果您真的想这样做,您必须将所有值存储到某个不被修改的地方。最简单的方法是在迭代之前对集合使用
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());
...
。。。
//对于我们团队颜色中的每种颜色,但不是我们的车型颜色,请删除
foreach(team.colors.ToList()中的var color)/好的,在对此处进行了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);
//循环浏览我们的颜色,删除不在新颜色列表中的颜色
对于(var i=0;ic.Id==team.colors[i].Id))
团队。颜色。移除(i);
这非常有效。您能给我举个例子吗,我无法让它工作此代码是错误的,如果删除任何元素,将跳过集合中的某些项目。例如:您有var arr=[“a”、“b”、“c”]
,并且在第一次迭代(i=0
)中删除位置0处的元素(元素“a”
)。在此之后,所有数组元素将向上移动一个位置,并且数组将是[“b”,“c”]
。因此,在下一次迭代(i=1
)中,您将检查位置1处的元素,它将是“c”
而不是“b”
。这是错误的。要解决这个问题,你必须从底部向顶部移动。我可以看到你在说什么,但我已经测试过了。我选择了前三项,然后将其保存到数据库中。然后我编辑了记录,取消选择了第一个项目,选择了另一个项目,效果很好。因此,我再次编辑了它,取消了所有选择,选择了一组新的颜色,它仍然有效。尝试同时删除数组中一个接一个的两种颜色(比如说第一种和第二种),你就会明白我的意思。第二种颜色将被跳过,并且不会被删除。或-尝试以下操作1)添加所有颜色并更新;2) 删除所有颜色并更新;你会发现每2种颜色都不会被去除好的,你是对的。你能发布一个如何解决这个问题的代码示例,这样我就可以把你的标记为答案了吗?我已经做了。