Entity Framework, вызывая Clear для ICollection, выдавая исключение - PullRequest
0 голосов
/ 20 января 2020

Потратив целый день, мне удалось добиться отличной работы модели данных сущностей, чтобы я мог добавить / удалить Subjects et c, где EnrolledFaces и KeyValuePairs также были автоматически удалены из SQL, когда тема также удаляется.

Однако я сейчас пытаюсь обновить KeyValuePairs Subject, и строка, которая вызывает исключение, помечена. Если я удаляю эту строку, все работает хорошо, за исключением, конечно, я получаю больше строк в таблице SubjectData.

using (var dbContext = new SubjectsDbContext(SqlConnectionStringHelper.GetSqlConnectionString()))
{
    var subject = dbContext.Subjects.Where(a => a.SubjectId == subjectId).FirstOrDefault();

    if (subject != null)
    {
        if(subject.EnrolledFace == null)
        {
            subject.EnrolledFace = new FaceImage();
        }
        subject.EnrolledFace.Image = subjectInfo.FaceImage;

        subject.KeyValues.Clear();  <<<<<<<< CAUSE OF THE EXCEPTION

        foreach (var kv in subjectInfo.KeyValues)
        {
            subject.KeyValues.Add(new KVPair { Key = kv.Key.ToUpper(), Value = kv.Value });
        }

        dbContext.SaveChanges();

        return true;
    }

    return false;
}

Выдается исключение:

Произошла ошибка при сохранении сущностей, которые не предоставляют свойства внешнего ключа для своих отношений. Свойство EntityEntries вернет значение NULL, поскольку один объект не может быть определен как источник исключения. Обработка исключений при сохранении может быть упрощена путем предоставления свойств внешнего ключа в типах объектов. Подробности см. В InnerException.

InnerException: связь из AssociationSet Subject_KeyValues ​​находится в состоянии «Удалено». Учитывая ограничения множественности, соответствующий Subject_KeyValues_Target также должен находиться в состоянии «Удалено».

Модель данных сущности объявлена ​​ниже:

public class SubjectsDbContext : DbContext
{
    public virtual DbSet<Subject> Subjects { get; set; }
    public virtual DbSet<FaceImage> EnrolledFaces { get; set; }
    public virtual DbSet<KVPair> KeyValuePairs { get; set; }

    public SubjectsDbContext(string connectionString) : base(connectionString)
    {
    }

    public SubjectsDbContext()
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Subject>().HasMany(x => x.KeyValues).WithRequired().WillCascadeOnDelete(true);
    }
}

public class Subject
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid SubjectId { get; set; }

    [Required]
    public virtual FaceImage EnrolledFace { get; set; }

    [Required]
    public DateTimeOffset EnrolledTime { get; set; }

    [Required]
    [Column(TypeName = "varchar")]
    [StringLength(64)]
    public string BiometricId { get; set; }

    public virtual ICollection<KVPair> KeyValues { get; set; }

    public Subject()
    {
        KeyValues = new List<KVPair>();
    }
}

[Table("SubjectFaces")]
public class FaceImage
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Required]
    public Guid FaceId { get; set; }

    [Required]
    public byte[] Image { get; set; }
}

[Table("SubjectData")]
public class KVPair
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Required]
    public Guid KVPairId { get; set; }

    [Required]
    [Column(TypeName = "varchar")]
    [StringLength(128)]
    public string Key { get; set; }

    [Column(TypeName = "varchar")]
    [StringLength(128)]
    public string Value { get; set; }
}

Как это исправить?

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