#c# #asp.net-core #.net-core #entity-framework-core #blazor-server-side
#c# #asp.net-core #.net-core #entity-framework-core #blazor-на стороне сервера
Вопрос:
Я сталкиваюсь с потерей с этим и новичком в Blazor и пытаюсь его изучить (.NET 5)
У меня простая модель:
public class Status
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime LastUpdatedOn { get; set; }
}
Startup.cs
Я регистрирую свою базу данных и службы.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("Default")),(ServiceLifetime.Scoped));
services.AddAutoMapper(typeof(Startup));
services.AddScoped<IStatusRepo, StatusRepo>();
services.AddScoped<IStatusService, StatusService>();
Код, лежащий в основе файла моего компонента, приведен ниже. GetStatus
Вызов возвращает dto, отличный от того, который принимает метод службы обновления статуса, поэтому я конвертирую его в UpdateStatus
метод.
public partial class EditStatus : ComponentBase
{
[Parameter]
public int StatusId { get; set; }
[Inject]
IStatusService StatusService { get; set; }
[Inject]
NavigationManager navigationManager { get; set; }
public bool ShowLoadError { get; set; } = false;
private StatusDetailDto StatusToEdit { get; set; } = new StatusDetailDto();
protected override async Task OnInitializedAsync()
{
await GetStatusToEdit(StatusId);
}
public async Task GetStatusToEdit(int statusId)
{
try
{
StatusToEdit = await StatusService.GetStatusById(statusId);
}
catch (Exception ex)
{
ShowLoadError = true;
}
}
protected async void UpdateStatus()
{
UpdateStatusDto updatedStatus = new UpdateStatusDto();
updatedStatus.Id = StatusToEdit.Id;
updatedStatus.Name = StatusToEdit.Name;
StatusDetailDto statusUpdated = await StatusService.UpdateStatus(updatedStatus);
if (statusUpdated != null)
{
navigationManager.NavigateTo("status/manage");
}
else
{
Console.WriteLine("No here");
}
}
}
Уровень обслуживания:
public async Task<StatusDetailDto> UpdateStatus(UpdateStatusDto statusDto)
{
Status statusToUpdate = mapper.Map<UpdateStatusDto, Status>(statusDto);
Status updatedStatus = await statusRepo.UpdateStatus(statusToUpdate);
return mapper.Map<Status, StatusDetailDto>(updatedStatus);
}
И репозиторий
public async Task<Status> UpdateStatus(Status Status)
{
if (Status is null)
throw new ArgumentNullException("Nulls are not allowed.");
try
{
Status.LastUpdatedOn = DateTime.Now;
// THIS LINE THROWS THE ERROR!
_dbContext.Entry(Status).State = EntityState.Modified;
await _dbContext.SaveChangesAsync();
return Status;
}
catch (Exception)
{
throw;
}
}
Возможно, мои сроки службы неверны? Я тоже пробовал переходное время жизни для своего dbcontext
. Что может вызвать эту ошибку?
Экземпляр объекта типа ‘Status’ не может быть отслежен, поскольку другой экземпляр с тем же значением ключа для {‘Id’} уже отслеживается.
Ответ №1:
Сначала исправьте загрузочный файл, удалив ServiceLifetime.Область действия из AddDbContext
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("Default")));
Затем измените код вашего UpdateStatus
public async Task<Status> UpdateStatus(Status status)
{
if (status is null) throw new ArgumentNullException("Nulls are not allowed.");
try
{
var existedItem=_dbContext.Set<Status>().FirstOrDefaultAsync(i=i.Id==status.id);
if(existedItem==null) throw new ArgumentNullException("Item is not found.");
existedItem.LastUpdatedOn = DateTime.Now;
_dbContext.Entry(existedItem).State = EntityState.Modified;
await _dbContext.SaveChangesAsync();
return Status;
}
catch (Exception)
{
throw;
}
}
Комментарии:
1. Зачем мне нужно снова получать товар, если он у меня уже есть в аргументах?
2. Извините, это не работает. Он по-прежнему выдает исключение и пропускает вызов SaveChanges.
3. Но ваш комментарий заставил меня исправить это аналогичным образом, так что спасибо!
4. Это может быть что-то другое. Я немного изменил ваш код, и он работал нормально. Я не пытался быть грубым, ценю ваш ответ.