JOCKH
JOCKH

Reputation: 407

How to make a foreign key optional for a TEntity using EF Core

I'm working on an Asp project targeted .Net 5 using EF Core as O/RM.

I have these entities:

Student

public string Id                { get; set; }
public string FirstName         { get; set; }
public string FamilyName        { get; set; }
public string StudentGuardianId { get; set; }
public byte[] Picture           { get; set; }

public virtual StudentGuardian StudentGuardian { get; set; }

StudentGuardian

public string      Id          { get; set; }
public string      FirstName   { get; set; }
public string      FamilyName  { get; set; }
public string      Address     { get; set; }
public string      Profession  { get; set; }
public string      PhoneNumber { get; set; }
public Nationality Nationality { get; set; }
public string      FullName    { get; set; }
public string      Email       { get; set; }
public byte[]      Picture     { get; set; }

public virtual ICollection<Student> Students { get; set; }

To configure relationships between entities, and configure entities properties constraints I used configuration profiles (They are a classes implements IEntityTypeConfiguration).

StudentEntityConfig

public class StudentEntityConfig:IEntityTypeConfiguration<Student>
{
        public void Configure( EntityTypeBuilder<Student> builder )
        {
            builder.HasKey(x => x.Id);

            builder.Property(x => x.FirstName).IsRequired();
            builder.Property(x => x.FamilyName).IsRequired();
            builder.Property(x => x.BirthDate).IsRequired();
            builder.Property(x => x.BirthPlace).IsRequired();
            builder.Property(x => x.Gender).IsRequired();
            builder.Property(x => x.Nationality).IsRequired();
            builder.Property(x => x.Address).IsRequired();
            builder.Property(x => x.DateOfRegistration).IsRequired();
            builder.Property(x => x.AcademicYearOfRegistration).IsRequired();
            
            builder.Property(x => x.StudyLevelId).IsRequired();
            builder.Property(x => x.GroupId).IsRequired();
        }
}

StudentGuardianEntityConfig

public class StudentGuardianEntityConfig:IEntityTypeConfiguration<StudentGuardian>
{
        public void Configure( EntityTypeBuilder<StudentGuardian> builder )
        {
            builder.HasKey(x => x.Id);

            builder.Property(x => x.FirstName).IsRequired();
            builder.Property(x => x.FamilyName).IsRequired();
            builder.Property(x => x.Address).IsRequired();
            builder.Property(x => x.Profession).IsRequired();
            builder.Property(x => x.PhoneNumber).IsRequired();
            builder.Property(x => x.Nationality).IsRequired();
        }
}

What is the problem?

The problem is automatically a relationship will be created between Student and StudentGuardian and ill enforce foreign key constraint, which means that when want to create a new Student I should set StudentGuardianId foreign key value.

So not every Student will has a Guardian.

What I want exactly?

I want to know how I can make the StudentGuardianId optional and can be inserted with no value.

I wish you understand the problem, so please is there any way to achieve my goal.

Upvotes: 0

Views: 1113

Answers (1)

Gert Arnold
Gert Arnold

Reputation: 109252

An enforced foreign key constraint doesn't mean it's required. It only means it requires that Student.StudentGuardianId values refer to actually existing StudentGuardian.IDs. But Student.StudentGuardianId can be null because the column is nullable unless you explicitly configure it as required.

Most of us, application developers, take it for granted that FKs are enforced. (Which is why we easily read it as "required"). But they need not be. For example, for database replication they may temporarily be released, not by removing them, but by not enforcing them. And sometimes, in legacy databases, some foreign keys are permanently unenforced (needless to say that this isn't an optimal situation).

Upvotes: 3

Related Questions