Хорошо, есть несколько проблем с этим кодом, которые вы должны рассмотреть, чтобы изменить:
public async Task<bool> AddPlayerRecord(PlayerStatRecord record)
{
_context.Players.PlayerStats.Add(record);
var result = await _context.SaveChangesAsync();
return result == 1;
}
Во-первых:
_context.Players.PlayerStats.Add(record);
Вы принимаете сущность PlayerStat, но затем пытаетесь добавитьэто в PlayerStats через коллекцию Players DbSet.Обычно вы добавляете PlayerStat либо через DbSet PlayerStats DbContext, либо к одному объекту Player.
Например:
_context.PlayerStats.Add(record);
или:
var player = _context.Players
.Include(x => x.PlayerStats)
.Single(x => x.PlayerId = record.PlayerId);
player.PlayerStats.Add(record);
Secondly: Вы должны не принимать сущности от клиента в ваших методах контроллера и, конечно, не доверять, что они точны, полны или каким-либо образом действительны.Веб-запросы могут быть перехвачены, а их полезные данные изменены.Даже если вы отправили данные из записи, когда страница была загружена, не верьте возвращающимся данным.Также не путайте данные, возвращающиеся для отслеживаемой сущности.Это не так.Это часть данных POCO, которая разделяет структуру объекта, но это не отслеживаемый объект.
Вместо этого вы всегда должны передавать модели представления POCO в / из веб-клиента, а затем проверять информацию, передаваемую по реальных данных до возможного применения изменений.Например: обработка переданной вами записи как модели представления:
public async Task<bool> AddPlayerRecord(PlayerStatRecord record)
{
// ToDo: Verify the current logged in session is active, and that the logged in
// user can modify the provided Player ID.
// Look up the player by ID. Throws ex. if player not found.
var player = _context.Players
.Include(x => x.PlayerStats)
.Single(x => x.PlayerId == record.PlayerId);
// Look up any related information.
var statistic = _context.Statistics.Single(x => x.StatisticId = record.StatisticId);
// Validate any data that was provided to ensure it was complete.
if(!record.IsComplete)
Throw new ArgumentException("The provided player statistic was not valid.");
// Populate a new player statistic entity, associate our references, and add it to
// the applicable player record.
player.PlayeerStats.Add(new PlayerStatRecord
{
Statistic = statistic,
// copy over other values and references...
});
var result = await _context.SaveChangesAsync();
return result == 1;
}
Однако вместо того, чтобы принимать PlayerStatRecord, метод должен принять PlayerStatViewModel или просто идентификаторы и значения, необходимые для построения статистики игрока после проверкичто данные полны и разрешены.Проблема с отправкой сущности заключается в том, что позже в будущем слишком легко «доверять» сущности и добавляет ее неподтвержденной или прикрепляет к контексту, который необходимо сохранить.