Не удается обновить столбец идентификаторов в Entity Framework Core после обновления до .Net Core 3.1.

После обновления до .Net Core 3.1 один из моих объектов выдает ошибку, если я пытаюсь обновить его с ошибкой «не удается обновить столбец идентификаторов в Entity Framework Core». Это происходит в присоединенном или отсоединенном состоянии.

Вот моя свободная конфигурация

modelBuilder.Entity<OrderStatus>(b =>
            {
                b.ToTable("OrderStatus");
                b.HasKey(e => e.OrderStatusId);
                b.HasKey(e => new { e.CompanyId, e.OrderId }); //CompositeKey
                b.Property(e => e.OrderStatusId).UseIdentityColumn();
            });

Я извлекаю объект и обновляю значение (не OrderStatusId) и вызываю save, и вот когда он взрывается.

var orderStatus = _context.OrderStatus.FirstOrDefault();
orderStatus.Total = 500;
_context.Entry(OrderStatus).State = EntityState.Modified;
await _context.SaveChangesAsync();

Я наткнулся на этот старый поток не может обновить столбец идентификаторов в Entity Framework Core в котором упоминается «исправление» добавления

b.Property(e => e.OrderStatusId).Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Ignore);

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

К вашему сведению, раньше я работал на EF core 3.0 и пытался обновить до 3.1.3, но это не имеет значения.

Должен ли я теперь добавлять это ко всем моим беглым определениям?

Предложения приветствуются!


person Raj    schedule 30.04.2020    source источник


Ответы (1)


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

Должен ли я теперь добавлять это ко всем моим беглым определениям?

Это необходимо только для столбцов идентификаторов, которые не являются первичным ключом (PK) таблицы (или Key в EF Core).

Что должно быть редко - вот почему у вас проблемы только с этой таблицей.

Но действительно ли вам нужен составной ПК (и в чем тогда смысл столбца идентификации)? Обратите внимание, что как и для любых вызовов Fluent, побеждает последний HasKey (API EF Core Fluent для определения PK), т.е. здесь

b.HasKey(e => e.OrderStatusId);
b.HasKey(e => new { e.CompanyId, e.OrderId }); //CompositeKey

линия

b.HasKey(e => e.OrderStatusId);

не имеет никакого эффекта, поэтому по умолчанию имеет право на обновление. Но тогда почему оно здесь? Может быть, намерение состояло в том, чтобы иметь идентификатор PK и составной альтернативный ключ? Другими словами, если конфиг был

b.HasKey(e => e.OrderStatusId);
b.HasAlternateKey(e => new { e.CompanyId, e.OrderId }); //CompositeKey

тогда у вас не будет такой проблемы и не нужно будет настраивать AfterSaveBehavior.

А если уж хотите составной ПК, то уберите вводящий в заблуждение

b.HasKey(e => e.OrderStatusId);

линии и используйте решение SetAfterSaveBehavior.

person Ivan Stoev    schedule 30.04.2020
comment
Хорошо, это имеет большой смысл. Я считаю, что мне нужен составной ключ в моей ситуации. (может быть заказ с несколькими CompanyId, поэтому каждый заказ обычно будет иметь несколько строк). Когда я пробую ваше изменение, оно действительно работает, НО OrderID устанавливается как FK, а CompanyID просто устанавливается не равным нулю. (Однако у ограничений есть ограничение с OrderID_CompanyID). Это ожидаемое поведение составного ключа? - person Raj; 30.04.2020
comment
Альтернативные ключи в базах данных называются уникальными ключами. Я не ожидаю изменений отношений FK, возможно, в вашей модели есть что-то, что требует явного отображения CompanyID как FK. Я не могу сказать точно, не видя всю модель. Но это было не главное, просто строка b.HasKey(e => e.OrderStatusId); была подозрительной. - person Ivan Stoev; 30.04.2020