отображение однонаправленного единицы на ноль или единицу с помощью составного ключа - PullRequest
0 голосов
/ 12 октября 2018

Существует два класса, унаследованных от одного базового класса (я полагаю, это не имеет значения), соответствующих двум таблицам в базе данных sqlite.
Оба эти класса содержат значения для лицензионного ключа и значения длязапись была создана и последний раз обновлялась.

Также следует отметить, что одна лицензия может иметь любое количество событий, связанных с ней, но только одно событие может быть определено для автоматического запуска для каждой лицензии.Кроме того, соединение является однонаправленным;объект автозапуска всегда будет ссылаться на событие, но не все события имеют объект автозапуска, ссылающийся на них, и все события не знают, являются ли они событием автозапуска или нет.

Определения классов:

public abstract class EntityBase : IModel, ITimestampedEntity
{
    public virtual string LicenseKey { get; set; }
    public virtual DateTime? CreatedAt { get; set; }
    public virtual DateTime? UpdatedAt { get; set; }
}

public class Event : EntityBase, IEvent
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
}

public class AutoStart : EntityBase
{
    public Event Event { get; set; }
}

Я предоставлю sql для двух таблиц в базе данных sqlite:

CREATE TABLE `event` (
  `id`  INTEGER NOT NULL,
  `name`    TEXT NOT NULL,
  `start_date`  TEXT,
  `end_date`    TEXT,
  `license_key` TEXT,
  `created_at`  TEXT,
  `updated_at`  TEXT,
  PRIMARY KEY(`id`,`license_key`)
);

CREATE TABLE `autostart_event` (
  `license_key` TEXT NOT NULL,
  `event_id`    INTEGER NOT NULL,
  `created_at`  TEXT,
  `updated_at`  TEXT,
  PRIMARY KEY(`license_key`),
  FOREIGN KEY(`license_key`) REFERENCES `event`(`license_key`) ON UPDATE CASCADE,
  FOREIGN KEY(`event_id`) REFERENCES `event`(`id`) ON UPDATE CASCADE
);

Обратите внимание, что мы используем больше sqlсоответствовать расписанию имен, чем EF6 будет использовать сам.По этой причине имена столбцов определены в отображении.

Таблицы отображаются с использованием Entity Framework Fluent API.Отображение, определенное в контексте, выглядит следующим образом:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Fluent API event table mapping properties
    var eventMapping = modelBuilder.Entity<Event>().ToTable("event");
    eventMapping.HasKey(@event => new { @event.Id, @event.LicenseKey }).Property(@event => @event.Id).HasColumnName("id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
    eventMapping.Property(@event => @event.Name).HasColumnName("name").IsRequired();
    eventMapping.Property(@event => @event.StartDate).HasColumnName("start_date");
    eventMapping.Property(@event => @event.EndDate).HasColumnName("end_date");
    eventMapping.Property(@event => @event.LicenseKey).HasColumnName("license_key");
    eventMapping.Property(@event => @event.CreatedAt).HasColumnName("created_at");
    eventMapping.Property(@event => @event.UpdatedAt).HasColumnName("updated_at");

    // Fluent API event_autostart table mapping properties
    var autoStartMapping = modelBuilder.Entity<AutoStart>().ToTable("autostart_event");
    autoStartMapping.HasKey(autoStart => autoStart.LicenseKey).Property(autoStart => autoStart.LicenseKey).HasColumnName("license_key");
    autoStartMapping.HasRequired(autoStart => autoStart.Event).WithRequiredPrincipal().Map(map => map.MapKey("event_id"));
    autoStartMapping.Property(autoStart => autoStart.CreatedAt).HasColumnName("created_at");
    autoStartMapping.Property(autoStart => autoStart.UpdatedAt).HasColumnName("updated_at");
}

Как показано здесь, таблица событий имеет составной индекс первичного ключа, составляя как id, так и license_key.
Объект автозапуска имеет только один первичный ключ: license_key (поскольку для каждой лицензии может быть определено только одно событие автозапуска).

Я могу сохранять и извлекать события из базы данных, но при сохранении объекта автозапуска выдается исключение, заявляющее:

SQL logic error foreign key mismatch - "autostart_event" referencing "event"

Я полагаю, что это связано с составным ключом иимена столбцов не по умолчанию (в конце концов, имя столбца - event_id, а не событие), однако я не смог найти, как правильно сопоставить имена столбцов для отношения один к одному или ноль-один.
Документация относится к методу HasForeignKey () , но он доступен только для объектов DependentNavigationPropertyConfiguration , которые возвращаются RequiredNavigationPropertyConfiguration . WithMany () вызов.Но поскольку здесь не так много отношений ...

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