Entity Framework Core - операция с базой данных, которая, как ожидается, повлияет на 1 строку (и), но фактически затронула 0 (и) строку (и) - PullRequest
0 голосов
/ 07 июня 2018

У меня следующая довольно сложная структура таблицы (имена были изменены, а некоторые поля удалены).Первоначально при добавлении или обновлении table1 добавлялись новые элементы в table2, поэтому я изменил отношение в table2 с наличия только одного первичного ключа на комбинированный ключ, чтобы гарантировать, что если элемент с Table1Id и Table2Id существует, он должен обновить егоиначе вставьте его.Table2 имеет много столбцов с CustomDataType, который является ссылкой на производные CustomType таблицы, в которые добавляются значения.

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

Кто-нибудь имеет представление о том, что я делаю здесь неправильно и как все исправить?

Вот снова отношения, которые я пытаюсь разрешить:

  • Table1 имеет много Table2 предметов
  • Table2 имеет много CustomDataType предметов и связано с Table1 через Table1Id;он также использует Table1Id вместе с Table2Id для идентификации уникальной строки
  • CustomDataType имеет уникальный Id и три столбца: CustomType1, CustomType2 и CustomType3
  • CustomType является родителем CustomType1, CustomType2 и CustomType3 и имеет уникальный Id и некоторые столбцы значений

Код:

    public class table1 : ClientChangeTracker
    {
      [Key]
      public string Table1Id{ get; set; }
      public IEnumerable<table2> Table2List { get; set;}
      //various other fields
    }

    public class table2 : ClientChangeTracker
    {
      public string Table1Id { get; set;}
      public string Table2Id { get; set;}
      public CustomDataType item1 { get; set; }
      public CustomDataType item2 { get; set; }
      //many other CustomDataType fields (about 20)
    }

    public class CustomDataType : ClientChangeTracker
    {
      [Key]
      [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      public long Id { get; set; }
      public IEnumerable<CustomType1> CustomType1 {get; set; }
      public IEnumerable<CustomType2> CustomType2 { get; set; }
      public IEnumerable<CustomType3> CustomType3 { get; set; }
    }

    public class CustomType1 : CustomType
    {
        //left empty to force creating different table for CustomType
    }

    public class CustomType2 : CustomType
    {
         //left empty to force creating different table for CustomType
    }

    public class CustomType3 : CustomType
    {
         //left empty to force creating different table for CustomType
    }

    public class CustomType
    {
      [Key]
      [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      public long Id { get; set; }
      public double Value1 { get; set; }
      public double Value2 { get; set; }
    }

В классе Context у меня есть следующее отображение, создающее комбинированный ключ, потому что только Table1Id в сочетании с Table2Id может дать уникальный результат:

modelBuilder.Entity<table2>()
  .HasKey(x => new {x.Table1Id, x.Table2Id}

Данные сохраняются в базе данных с использованиемследующий код:

 public Entities.Table1 Save(Entities.Table1 table1)
 {
     _context.ChangeTracker.TrackGraph(table1, e => EntityHelper.ApplyStateUsingIsKeySet(e.Entry));

     if (_context.table1s.Any(x => x.Table1Id == table1.Table1Id))
     {
         LastSaveMode = SaveMode.Update;
         var newTable1 = _context.table1s.Update(table1).Entity;
         NumberOfObjectsWrittenToUnderlyingDatabase = _context.SaveChanges();
         return newTable1;
     }
     else
     {
         LastSaveMode = SaveMode.Add;
         var updatedTable1 = _context.table1s.Add(table1).Entity;
         NumberOfObjectsWrittenToUnderlyingDatabase = _context.SaveChanges();
         return updatedTable1;
     }                                          
 }

ApplyStateUsingIsKeySet Код:

public class EntityHelper
{
    internal static void ApplyStateUsingIsKeySet(EntityEntry entry)
    {
        if (entry.IsKeySet)
        {
            entry.State = ((ClientChangeTracker)entry.Entity).IsDirty ? EntityState.Modified : EntityState.Unchanged;
        }
        else
        {
            entry.State = EntityState.Added;
        }
    }
}

Таблицы нормально создаются в базе данных, однако при запуске приложения возникает ошибка:

Операция базы данных, как ожидается, повлияет на 1 строку (и), но фактически затронула 0 строк (а)

...