entity framework更新查找表正在向另一个表添加项目

我有一个查找表的问题。 我有一个表单,允许我从列表中选择颜色,该列表将成为团队的一部分。 更新方法如下所示:

[HttpPut] [Route("")] ///  /// Update a team ///  /// The team model /// Nothing public async Task 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"); // Make changes to our team team.Name = model.Name; team.Sport = model.Sport; // Find out which colours need adding and removing var coloursToRemove = GetDifference(team.Colours, model.Colours); var coloursToAdd = GetDifference(model.Colours, team.Colours); // Loop through our colours to remove and remove them if (coloursToRemove.Count() > 0) foreach (var colour in coloursToRemove) team.Colours.Remove(colour); // Loop through the colours to add and add them if (coloursToAdd.Count() > 0) foreach (var colour in coloursToAdd) team.Colours.Add(colour); // Update the team this.service.Update(team); // Save the database changes await this.unitOfWork.SaveChangesAsync(); // Return Ok return Ok(model); } private IList GetDifference(IList firstList, IList secondList) { // Create a new list var list = new List(); // Loop through the first list foreach (var first in firstList) { // Create a boolean and set to false var found = false; // Loop through the second list foreach (var second in secondList) { // If the first item id is the same as the second item id if (first.Id == second.Id) { // Mark it has being found found = true; } } // After we have looped through the second list, if we haven't found a match if (!found) { // Add the item to our list list.Add(first); } } // Return our differences return list; } 

如果我在unitOfWork.SaveChangesAsync()上放置一个断点,那么我可以看到团队颜色正在使用我数据库中已有的颜色(所有id匹配。但是一旦执行了SaveChangesAsync ,它就会在Colors中创建一个新行表格与我刚刚选择的颜色重复。我不希望它创建一个新行,我希望它使用所选颜色。

我不确定如何提供更多信息; 我希望这足以说明某人能够帮助我!

更新

所以我决定查看生成的SQL。 我的Colors表中有一个颜色,如下所示:

10红色(Pms200)ff0000

因此Id10名称红色(Pms200)Hexff0000 。 如果我在编辑团队时选择该颜色并按提交。 它运行上面显示的Update方法,我已经更改了我的DbContext ,通过在构造函数中添加以下行来记录sql:

 this.Database.Log = s => Debug.WriteLine(s); 

因此,当SaveChangesAsync代码执行时,将生成以下SQL:

 Started transaction at 13/04/2015 12:25:03 +01:00 UPDATE [dbo].[Teams] SET [Name] = @0, [Sport] = @1 WHERE ([Id] = @2) -- @0: 'Testing' (Type = String, Size = -1) -- @1: 'ultimate-frisbee' (Type = String, Size = -1) -- @2: '1' (Type = Int32) -- Executing asynchronously at 13/04/2015 12:25:03 +01:00 -- Completed in 5 ms with result: 1 INSERT [dbo].[Colours]([Name], [Hex]) VALUES (@0, @1) SELECT [Id] FROM [dbo].[Colours] WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity() -- @0: 'Red (Pms200)' (Type = String, Size = -1) -- @1: 'ff0000' (Type = String, Size = -1) -- Executing asynchronously at 13/04/2015 12:25:03 +01:00 -- Completed in 1 ms with result: SqlDataReader INSERT [dbo].[TeamColours]([TeamId], [ColourId]) VALUES (@0, @1) -- @0: '1' (Type = Int32) -- @1: '43' (Type = Int32) -- Executing asynchronously at 13/04/2015 12:25:03 +01:00 -- Completed in 1 ms with result: 1 Committed transaction at 13/04/2015 12:25:03 +01:00 Closed connection at 13/04/2015 12:25:03 +01:00 

现在问题是它应该只在TeamColours表中插入一些东西而不是Colors表。 我无法弄清楚为什么……

因为有人要求查看我的UnitOfWork类,这里是:

 public class UnitOfWork : IUnitOfWork where TContext : DbContext, new() { private readonly DbContext context; private Dictionary repositories; public DbContext Context { get { return this.context; } } public UnitOfWork() { this.context = new TContext(); repositories = new Dictionary(); } public IRepository GetRepository() where TEntity : class { if (repositories.Keys.Contains(typeof(TEntity))) return repositories[typeof(TEntity)] as IRepository; var repository = new Repository(context); repositories.Add(typeof(TEntity), repository); return repository; } public async Task SaveChangesAsync() { try { await this.context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException ex) { ex.Entries.First().Reload(); } } public void Dispose() { this.context.Dispose(); } } 

虽然我确信这不会导致问题。

试试这个

 public async Task 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"); // Make changes to our team team.Name = model.Name; team.Sport = model.Sport; //remove foreach (var colour in team.Colours.ToList()) { if (!model.Colours.Any(c => c.Id == colour.Id)) team.Colours.Remove(colour); } //add foreach (var colour in model.Colours) { if (!team.Colours.Any(c => c.Id == colour.Id)) team.Colours.Add(colour); } // Update the team this.service.Update(team); // Save the database changes await this.unitOfWork.SaveChangesAsync(); // Return Ok return Ok(model); } 

Model.Colors与上下文无关。 所以你的Db Context试图添加新的。

1 – 从存储库获取颜色

 var newColours = repository.ListColours(model.Colors.Select(m=>m.Id)); 

2-为团队分配新颜色

 team.Colours = newColours; this.service.Update(team); await this.unitOfWork.SaveChangesAsync(); 

EF将自动执行删除和添加操作。

我还没有测试过这段代码。 但我希望EntityFramework比我更聪明。