В моей базе данных на основе модели данных / Entity Framework (EFCore) определены следующие отношения:
- A
Person.cs
, которая реализует интерфейс IRecord. Person
имеет List
из ExternalId.cs
объектов. - Класс
ExternalId.cs
имеет свойство, обратное к интерфейсу IRecord
. Это отношение один ко многим (от одного IRecord
ко многим ExternalId
).
Желаемое поведение состоит в том, что при удалении объекта IRecord
зависимые внешние идентификаторы тоже.
Другие модели / таблицы в моей базе данных также реализуют этот интерфейс (Regulation.cs
, Organization.cs
, et c.) И внешние идентификаторы, на которые они ссылаются, при условии того же поведения OnDelete
.
Это то, что я настроил в ApplicationDbContext.cs
:
modelBuilder.Entity<Customer>()
.HasMany(rec => rec.ExternalIds)
.WithOne(extId => (Customer)extId.Record)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Person>()
.HasMany(rec => rec.ExternalIds)
.WithOne(extId => (Person)extId.Record)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Organization>()
.HasMany(rec => rec.ExternalIds)
.WithOne(extId => (Organization)extId.Record)
.OnDelete(DeleteBehavior.Cascade);
Что я делаю неправильно, что это работает не так, как ожидалось?
Это различные модели, описанные выше:
IRecord:
public interface IRecord {
int Id { get; set; }
}
ExternalId:
public class ExternalId : IRecord
{
public int Id { get; set; }
[InverseProperty("ExternalIds")]
public IRecord Record { get; set; }
public string Service { get; set; } // Comes from DataSource Enum
public string Purpose { get; set; } // Comes from IdType Enum
public string Value { get; set; } // Value
}
Person
public class Person: IRecord
{
#region Properties
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[DataType(DataType.Date)]
public DateTime? DateOfBirth { get; set; }
public int ContactInformationId { get; set; }
public virtual ContactInformation ContactInformation { get; set; }
public string PictureURL { get; set; }
public string Title { get; set; }
public List<ExternalId> ExternalIds { get; set; }
}
Это имена таблиц:
public DbSet<ExternalId> Identifiers { get; set; }
public DbSet<Person> People { get; set; }
Когда я пытаюсь удалить объекты Person в моей базе данных (через _context.People.RemoveRange(peopleToDelete)
), я получаю следующую ошибку:
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details.
---> Microsoft.Data.SqlClient.SqlException (0x80131904): The DELETE statement conflicted with the REFERENCE constraint "FK_Identifiers_People_PersonId". The conflict occurred in database "OurGov", table "dbo.Identifiers", column 'PersonId'.
The DELETE statement conflicted with the REFERENCE constraint "FK_Identifiers_People_PersonId". The conflict occurred in database "OurGov", table "dbo.Identifiers", column 'PersonId'.
Неправильно ли я установил отношения? Я чувствую, что это связано с тем, что мое свойство отношений является интерфейсом, который я должен был привести.
Обновление - 2020-05-05
Я заметил, что моя SQL Таблица, которая была сгенерирована, имеет три столбца, PersonId, Регламент, RecordId. Класс Person имеет свой идентификатор, сохраненный в PersonId, в отличие от RecordId. Я могу видеть, что это было сгенерировано во время одной из моих миграций некоторое время назад.
Я подозреваю, что мог добавить миграцию и обновить базу данных до добавления обратного свойства и / или маркировки класса Person (а также Регламента). class) как реализующий интерфейс Record.
Как я могу очистить это, чтобы отбросить эти столбцы и чтобы все мои объекты IRecord упоминались в RecordId?