Это моя модель, и между программой обучения и учебным модулем установлены отношения «многие ко многим». Следующее, что я не уверен, что это наилучшая практика, — это выпуск табличного обучения. Для этого требуется соединение «1 ко многим» с этим «многим ко многим» LearningProgrammeAssignment. Нужно ли создавать идентификатор в LearningProgrammeAssignment? Или я могу просто сослаться на него в LearningRelease?
public class MyContext : DbContext
{
public DbSet<LearningProgramme> LearningProgrammes { get; set; }
public DbSet<LearningModule> LearningModules { get; set; }
public DbSet<LearningProgrammeAssignment> LearningProgrammeAssignments { get; set; }
public DbSet<LearningRelease> LearningReleases { get; set; }
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<LearningProgrammeAssignment>()
.HasKey(p => new { p.LearningModuleId, p.LearningProgrammeId });
}
public class LearningProgramme
{
public int LearningProgrammeId { get; set; }
public string LearningProgrammeTitle { get; set; }
public List<LearningProgrammeAssignment> LearningProgrammeAssignments { get; set; }
}
public class LearningModule
{
public int LearningModuleId { get; set; }
public string LearningModuleTitle { get; set; }
public List<LearningProgrammeAssignment> LearningProgrammeAssignments { get; set; }
}
public class LearningProgrammeAssignment
{
public int LearningProgrammeId { get; set; }
public int LearningModuleId { get; set; }
public LearningProgramme LearningProgramme { get; set; }
public LearningModule LearningModule { get; set; }
}
public class LearningRelease
{
public int LearningReleaseId { get; set; }
public int systemcode { get; set; }
public DateTime ReleaseDate { get; set; }
//add in the LearningProgrammeAssignment id
}





Поскольку вам нужна связь «один ко многим» между LearningRelease и LearningProgrammeAssignment, вам нужно определить LearningReleaseId внутри LearningProgrammeAssignment в качестве внешнего ключа, чтобы правильно настроить связь:
namespace DL.SO.EFCore.Learning.Data.Entities
{
public class LearningProgrammeAssignment
{
public int LearningProgrammeId { get; set; }
public LearningProgramme LearningProgramme { get; set; }
public int LearningModuleId { get; set; }
public LearningModule LearningModule { get; set; }
public int LearningReleaseId { get; set; }
// Optional
public LearningRelease LearningRelease { get; set; }
}
}
Свойство навигации LearningRelease является необязательным. Это зависит от того, хотите вы этого или нет. То же самое для отношения «многие» внутри LearningRelease:
using System;
using System.Collections.Generic;
namespace DL.SO.EFCore.Learning.Data.Entities
{
public class LearningRelease
{
public int LearningReleaseId { get; set; }
public int SystemCode { get; set; }
public DateTime ReleaseDate { get; set; }
public List<LearningProgrammeAssignment> LearningProgrammeAssignments { get; set; }
}
}
Затем вам просто нужно настроить их обычным способом:
using DL.SO.EFCore.Learning.Data.Configurations;
using DL.SO.EFCore.Learning.Data.Entities;
using Microsoft.EntityFrameworkCore;
namespace DL.SO.EFCore.Learning.Data
{
public class LearningDbContext : DbContext
{
public LearningDbContext(DbContextOptions<LearningDbContext> options) : base(options) { }
public DbSet<LearningModule> LearningModules { get; set; }
public DbSet<LearningProgramme> LearningProgrammes { get; set; }
public DbSet<LearningProgrammeAssignment> LearningProgrammeAssignments { get; set; }
public DbSet<LearningRelease> LearningReleases { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfiguration(new LearningModuleConfiguration());
modelBuilder.ApplyConfiguration(new LearningProgrammeConfiguration());
modelBuilder.ApplyConfiguration(new LearningProgrammeAssignmentConfiguration());
modelBuilder.ApplyConfiguration(new LearningReleaseConfiguration());
}
}
}
Ключ в LearningProgrammeAssignmentConfiguration (другие конфигурации для ясности не выложены):
using DL.SO.EFCore.Learning.Data.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace DL.SO.EFCore.Learning.Data.Configurations
{
public class LearningProgrammeAssignmentConfiguration : IEntityTypeConfiguration<LearningProgrammeAssignment>
{
public void Configure(EntityTypeBuilder<LearningProgrammeAssignment> builder)
{
// Composite key
builder.HasKey(x => new { x.LearningModuleId, x.LearningProgrammeId });
// Setup Many-To-Many relationship between LearningModule and LearningProgramme
builder.HasOne(x => x.LearningModule)
.WithMany(x => x.LearningProgrammeAssignments)
.HasForeignKey(x => x.LearningModuleId);
builder.HasOne(x => x.LearningProgramme)
.WithMany(x => x.LearningProgrammeAssignments)
.HasForeignKey(x => x.LearningProgrammeId);
// Setup One-To-Many relationship between LearningRelease and LearningProgrammeAssignment
builder.HasOne(x => x.LearningRelease)
.WithMany(x => x.LearningProgrammeAssignments)
.HasForeignKey(x => x.LearningReleaseId);
// Alternately:
// you don't have to put the navigation property LearningRelease
// in this LearningProgrammeAssignment, as you can setup
// One-To-Many relationship without navigation properties like
// this:
//builder.HasOne<LearningRelease>()
// .WithMany()
// .HasForeignKey(x => x.LearningReleaseId);
builder.ToTable("LearningProgrammeAssignment");
}
}
}
И результат:
Спасибо, Дэвид, прекрасное объяснение
Похоже,
LearningProgrammeAssignment— это не просто таблица присоединения. Возможно, вам лучше добавить свой собственный первичный ключ, как вы думали. Затем вы можете связать это сLearningReleaseкак с обычной сущностью.