Как я могу разрешить сообщение «Свойство Id является частью ключевой информации объекта и не может быть изменено»? - PullRequest
0 голосов
/ 03 сентября 2018

Я провел некоторый поиск и понимаю, что это из соображений безопасности, так как EF не хочет, чтобы вы обновляли два элемента одновременно. Я также читал, что если какая-либо модель не имеет определенного первичного ключа, вы можете получить эту ошибку.

Мое приложение настроено с сеткой KendoUI, которая показывает связанные данные, доставленные через представление в моей базе данных SQL. Две таблицы, которые он показывает, это Car и Booking через модель представления с именем CarsAndBookingsViewModel

Car.cs

[Key]
public int Id { get; set; }
public string Reg { get; set; }
public string Make { get; set; }
public string Model { get; set; }

Booking.cs

[Key]
public int Id { get; set; }
public DateTime BookingStart { get; set; }
public DateTime BookingEnd { get; set; }
public int? Car_Id { get; set; }

CarsAndBookingsViewModel.cs

[Key]
public int Id { get; set; }
public string Reg { get; set; }
public string Make { get; set; }
public string Model { get; set; }

public DateTime BookingStart { get; set; }
public DateTime BookingEnd { get; set; }
public int? Car_Id { get; set; }

Код для сетки следующий:

@(Html.Kendo().Grid<MyProject.ViewModels.CarsAndBookingsViewModel>()
.Name("Bookings")
.Columns(columns => {
    columns.Bound(c => c.Id);
    columns.Bound(c => c.Car_Id);
    columns.Bound(c => c.Reg);
    columns.Bound(c => c.Make);
    columns.Bound(c => c.Model);
    columns.Bound(c => c.BookingStart).Format("{0:dd/MM/yyyy}");
    columns.Bound(c => c.BookingEnd).Format("{0:dd/MM/yyyy}");
    columns.Command(command => { command.Edit(); }).Width(250);
})
.Pageable()
.Sortable()
.Groupable()
.Editable(editable => editable.Mode(GridEditMode.InLine))
.DataSource(dataSource => dataSource
    .Ajax()
    .Model(model => {
        model.Id(p => p.Id);
        model.Field(p => p.Id).Editable(false);
        model.Field(p => p.Car_Id).Editable(false);
    })
    .Read(read => read.Action("GetBookings", "Bookings"))
        .Update(update => update.Action("UpdateBooking", "Booking")))
))

Мы разрешаем пользователю обновлять данные с помощью встроенных функций редактирования сетки. Вот метод UpdateBooking, который передается в viewmodel, используя Automapper для сопоставления свойств, он пытается обновить только измененные данные для обеих таблиц.

Automapper Global Config

Mapper.Initialize(cfg => {
    cfg.CreateMap<CarsAndBookingsViewModel, Car>();
    cfg.CreateMap<CarsAndBookingsViewModel, Booking>();
});

Обновление метода бронирования

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateBookings([DataSourceRequest] DataSourceRequest request, BookingViewModel vm)
    {
        if (ModelState.IsValid)
        {
            //Update any changed booking info
            Booking booking = unitOfWork.BookingRepository.FindSingleOrDefault(s => s.Id == vm.Car_Id);
            Mapper.Map(vm, booking);
            unitOfWork.BookingRepository.Update(booking);

            //Update any changed car info
            Car car = unitOfWork.CarRepository.FindSingleOrDefault(vm.Id);
            Mapper.Map(vm, car);
            unitOfWork.CarRepository.Update(car);

            unitOfWork.Save();
        }
        return Json(new[] { vm }.ToDataSourceResult(request, ModelState));
    }

Я использую общий репозиторий, метод для FindSingleOrDefault выглядит следующим образом:

    public TEntity FindSingleOrDefault(Expression<Func<TEntity, bool>> predicate)
    {
        return context.Set<TEntity>().Single(predicate);
    }

Когда мое приложение запускает этот метод обновления, я получаю сообщение об ошибке при достижении unitOfWork.BookingRepository.Update(booking);:

The property 'Id' is part of the object's key information and cannot be modified. '

   public virtual void Update(TEntity entityToUpdate)
    {
        dbSet.Attach(entityToUpdate);//Error triggers here
        context.Entry(entityToUpdate).State = EntityState.Modified;
    }

Я не уверен, что делаю неправильно, я гарантировал, что добавил ключевые записи в модели и модель представления. Я не пытаюсь обновить Id, но я предполагаю, что он передается со всем остальным, и поэтому попытка делается, если это так, мне нужно предотвратить его, но я не знаю как. Любая помощь приветствуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...