我正在使用EF Core将新游戏添加到正在构建的Sudoku API中。每个游戏都有一个可以担任多个角色的用户。每当我添加新游戏时,我都必须手动拉用户角色并将其添加回上下文中,否则它们将丢失。同样,当我添加新游戏时,可能会丢失用户所有其他先前的游戏。我在做什么错了?
我尝试过
_context.Games.Add(game);
这导致了一系列问题,然后我尝试了
_context.Games.Update(game);
但我遇到了当前问题:
public async Task<Game> CreateGame(CreateGameRO createGameRO) {
var userActionResult =
await _userService.GetUser(createGameRO.UserId);
var difficultyActionResult =
await _difficultiesService.GetDifficulty(createGameRO.DifficultyId);
SudokuMatrix matrix = new SudokuMatrix();
matrix.GenerateSolution();
Game game = new Game(
userActionResult.Value,
matrix,
difficultyActionResult.Value);
// EF Core loses reference to the users roles when creating new games.
// Before we save the new game we pull a reference to the users roles...
var user = game.User;
var userRoles = _context.UsersRoles.Where(u => u.UserId == user.Id).ToList();
//var userGames = _context.Games.Where(g => g.UserId == user.Id).ToList();
_context.Games.Update(game);
await _context.SaveChangesAsync();
// ...then we reattach the users roles to the data context.
_context.UsersRoles.AddRange(userRoles);
//_context.Games.AddRange(userGames);
await _context.SaveChangesAsync();
return game;
}
我在应用程序中添加了日志记录,并注意到以下生成的SQL命令:
DELETE FROM "Games"
WHERE "Id" = @p0;
DELETE FROM "Games"
WHERE "Id" = @p1;
DELETE FROM "SudokuCells"
WHERE "Id" = @p2;
DELETE FROM "SudokuCells"
WHERE "Id" = @p3;
DELETE FROM "SudokuCells"
WHERE "Id" = @p4;
发生这种情况的情况如下...假设我创建了一个用户Dean Winchester,然后添加了另一个用户Sam Winchester。然后为Dean创建两个新游戏,一切都很好,为Sam创建两个新游戏,一切都还不错...然后为Dean创建另一个游戏,并创建上面的SQL,并删除前两个游戏。 / p>
答案 0 :(得分:0)
由于没有其他人可以回答这个问题,因此我将继续这样做。
据推测,我正在使用WebAPI在不连接的环境中工作,除非我特别跟踪它们,否则上下文不了解用户的其他游戏和角色。但是,我已经在日志中记录了EF核心消失的证据,这是跟踪用户游戏和角色的方式...并删除它们!
这种行为对我来说毫无意义,如果有人可以解释以这种方式处理它的基本逻辑,我将不胜感激。对我来说,更新语句封装了删除是很直观的。
我的解决方案现在看起来像这样:
Game game = new Game(
userActionResult.Value,
matrix,
difficultyActionResult.Value);
var user = await _context.Users
.FirstOrDefaultAsync(u => u.Id == userActionResult.Value.Id);
var userRoles = await _context.UsersRoles
.Where(ur => ur.UserId == user.Id)
.ToListAsync();
var userGames = await _context.Games
.Where(g => g.UserId == user.Id)
.ToListAsync();
_context.Games.Update(game);
await _context.SaveChangesAsync();
_context.UsersRoles.AddRange(userRoles);
await _context.SaveChangesAsync();
_context.Games.UpdateRange(userGames);
await _context.SaveChangesAsync();
我必须三遍数据库,以保护我一开始就不想接触的数据……这很愚蠢,但是可以。
我对这种解决方案不满意。假设一个用户玩了1000场游戏?我必须将所有1000场比赛拉入内存...添加我的新游戏... EF核心然后删除所有先前的1000场比赛...然后我必须重新添加1000场比赛?