У меня следующая довольно сложная структура таблицы (имена были изменены, а некоторые поля удалены).Первоначально при добавлении или обновлении 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 строк (а)