I have a class Personnage
which should own multiple Histoires
and should have one Default Histoire
.
Here are the classes :
public class Personnage
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Nom { get; set; }
public int? DefaultHistoireId { get; set; }
public virtual Histoire? DefaultHistoire { get; set; }
public List<Histoire> Histoires { get; set; } = new List<Histoire>();
}
public class Histoire
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Nom { get; set; }
public DateTime DateDebut { get; set; }
public DateTime? DateFin { get; set; } = null;
public List<Dialogue> Dialogues { get; set; } = new List<Dialogue>();
public int PersonnageId { get; set; }
public virtual Personnage Personnage { get; set; }
public int? DefaultForPersonnageId { get; set; } = null;
public virtual Personnage? DefaultForPersonnage { get; set; } = null;
}
I have to create the Personnage first, so the relationship between Personnage.DefaultHistoire
and Histoire
should be optional.
I tried to make the properties Personnage.DefaultHistoire
and Personnage.DefaultHistoireId
as nullable "?" in my code, and added this to my DbContext.OnModelCreating
:
modelBuilder
.Entity<Personnage>()
.HasOne(x => x.DefaultHistoire)
.WithOne(x => x.DefaultForPersonnage)
.IsRequired(false)
.HasForeignKey<Histoire>(x => x.DefaultForPersonnageId)
.HasPrincipalKey<Personnage>(x => x.DefaultHistoireId)
.OnDelete(DeleteBehavior.Cascade);
But in the Migration generated code, it still make the property as nullable: false
:
migrationBuilder.CreateTable(
name: "Personnages",
schema: "dbo",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Nom = table.Column<string>(type: "text", nullable: false),
DefaultHistoireId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Personnages", x => x.Id);
table.UniqueConstraint("AK_Personnages_DefaultHistoireId", x => x.DefaultHistoireId);
});
How can I mark this relationship as optional ?
CodePudding user response:
.HasPrincipalKey<Personnage>(x => x.DefaultHistoireId);
, then Personnage.DefaultHistoireId
will act like a primary key, unique value and not nullable.
Maybe Histoire.DefaultForPersonnageId
and Histoire.DefaultForPersonnage
can be removed and Personnage.DefaultHistoireId
reference directly Histoire.Id
:
modelBuilder
.Entity<Personnage>()
.HasOne(x => x.DefaultHistoire)
.WithOne()
.HasForeignKey<Personnage>(x => x.DefaultHistoireId)
.OnDelete(DeleteBehavior.Cascade);
public class Histoire
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Nom { get; set; }
public DateTime DateDebut { get; set; }
public DateTime? DateFin { get; set; } = null;
public List<Dialogue> Dialogues { get; set; } = new List<Dialogue>();
public int PersonnageId { get; set; }
public virtual Personnage Personnage { get; set; }
//public int? DefaultForPersonnageId { get; set; } = null;
//public virtual Personnage? DefaultForPersonnage { get; set; } = null;
}