Существует два класса, унаследованных от одного базового класса (я полагаю, это не имеет значения), соответствующих двум таблицам в базе данных 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 () вызов.Но поскольку здесь не так много отношений ...