Требуемый связанный объект, вызывающий ошибки проверки

#c# #entity-framework

#c# #entity-framework

Вопрос:

У меня есть что-то вроде следующего:

 public class EntityA
{
    [Required]
    long? EntityBId { get; set; }

    [ForeignKey("EntityBId ")]
    public virtual EntityB { get; set; }
}

public class EntityB
{
    [Key]
    long EntityBId { get; set; }
}
  

Когда я использую его следующим образом, я получаю ошибку проверки, потому что требуемое свойство EntityBId равно null.

 EntityA a = new EntityA();
a.EntityB = new EntityB();
dbContext.EntityAs.Add(EntityA);
dbContext.SaveChanges();
  

Однако, если я удалю [Required] атрибут, то оба EntityA и EntityB будут добавлены в базу данных и EntityBId будут заполнены SaveChanges вызовом.

Как я могу пометить EntityBId как [Required] и избежать сбоя проверки entity framework?

Комментарии:

1. Зачем вам нужно пометить его как [Required] , если вам не нужно, чтобы он был обязательным?

2. @Alexander это обязательно

Ответ №1:

Смотрите эту ссылку для использования требуемой аннотации:https://learn.microsoft.com/en-us/ef/ef6/modeling/code-first/data-annotations

«Требуемая аннотация сообщает EF, что требуется определенное свойство.

Добавление Required к свойству Title заставит EF (и MVC) убедиться, что в этом свойстве есть данные.»

итак, вам нужно решить, хотите ли вы аннотацию [Required], тогда это означает, что она не разрешит свойство с нулевым значением. И если вас устраивает значение null, удалите аннотацию [Обязательно].

Комментарии:

1. Свойство не должно быть нулевым. Это идентификатор требуемого связанного объекта. Связь устанавливается путем присвоения экземпляра виртуальному свойству для связанного объекта. Затем entity Framework заполняет идентификатор на своей стороне во время вызова SaveChanges. Что и происходит, если ему передается его собственная проверка.

2. если вы измените его с nullable<long>(длинный?) для параметра long по умолчанию будет установлено значение 0, а EF автоматически присвоит правильный идентификатор при сохранении.

3. Возможно, не уверен, обеспечит ли это желаемое поведение. Мне придется протестировать. Проблема может заключаться в том, что 0 является допустимым значением, указывающим на отдельную запись. Я не уверен, как entity Framework узнает, поддерживается ли указывать на запись 0 или присваивать значение из вставляемой новой записи.

4. @denver — Когда вы установите свойство навигации (виртуальное свойство) в значение instance EF правильно установит foreign key в идентификатор, созданный для указанной записи. Попробуйте.

5. Проверял, согласно моему последнему комментарию, если вы установили идентификатор равным 0, у entity framework возникает проблема и выдается исключение. Это меня не удивляет, потому что entity framework поставляется с противоречивой информацией. Я предполагаю, потому что внешний ключ имеет идентификатор, подразумевающий, что он уже есть в базе данных, в то время как экземпляр свойства навигации (virtual property) не является и не имеет идентификатора.

Ответ №2:

Может быть два сценария:

Первый: EntityB уже существующий в базе данных, и вы указываете EntityBId из EntityB на EntityBId ForeignKey из нового EntityA следующим образом, и в этом случае только EntityA будет вставлен в базу данных:

 EntityB entityB = dbContext.EntityBs.FirstOrDefault(yourCondition) 

EntityA entityA = new EntityA();
entityA.EntityBId = entityB.EntityBId; // <-- assign `ForeignKey` value instead of navigation property value, hence no required validation error will occur

dbContext.EntityAs.Add(entityA);
dbContext.SaveChanges();
  

Second: EntityB еще не существует в базе данных, и он будет заново вставлен в базу данных вместе с EntityA . Итак, в этом случае ваш код должен быть следующим:

 EntityB entityB = new EntityB();
dbContext.EntityBs.Add(entityB);

EntityA entityA = new EntityA();
entityA.EntityBId = entityB.EntityBId; // <-- assign `ForeignKey` value instead of navigation property value, hence no required validation error will occur
dbContext.EntityAs.Add(entityA);
dbContext.SaveChanges();
  

Теперь решите, каков ваш сценарий, и действуйте соответственно.

Комментарии:

1. Вторая ситуация в игре. Предоставленный вами код не будет работать, поскольку EntityB.EntityBId имеет значение null до вызова SaveChanges.

2. @denver The code you provide will not work because entityB.EntityBId is null — Нет! это сработает. EF достаточно умен, чтобы поддерживать это во время вставки.

3. Попробуйте свой код. Вы устанавливаете EntityA.EntityBId = null (эта строка ничего не делает). Затем проверка завершится неудачей, поскольку EntityBId помечен как обязательный. Если EntityBId не был отмечен, required entity framework установит связь во время вставки.

4. @denver не EntityBId является автоматически увеличиваемым первичным ключом?

5. EntityBId — это первичный ключ, я полагаю, что по умолчанию он автоматически увеличивается.