Marcos Lima
Marcos Lima

Reputation: 771

Duplicate key and table field in one-to-zero-or-one relation

For a metaphor here, a person can have zero or one car, and one car belongs only to one person.

I have a database that looks like this:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual Car Car { get; set; }
}

public class Car
{
    public int PersonId { get; set; }
    public virtual Person Person { get; set; }

    public string Model { get; set; }
}

I want to have a link from the person to its car, if existent, and from the car to its person. So my EntityTypeConfigurations are like so:

public class PersonConfig : EntityTypeConfiguration<Person>
{
    public PersonConfig()
    {
        ToTable("tblPerson");

        HasKey(s => s.Id)
            .Property(s => s.Id)
            .HasColumnName("idPerson");

        Property(s => s.Name)
            .HasColumnName("strName")
            .IsRequired();

        HasOptional(a => a.Car)
            .WithOptionalPrincipal();
    }
}

public class CarConfig : EntityTypeConfiguration<Car>
{
    public CarConfig()
    {
        ToTable("tblCar");

        HasKey(s => s.PersonId)
            .Property(s => s.PersonId)
            .HasColumnName("idPerson");

        Property(s => s.Model)
            .HasColumnName("strModel")
            .IsRequired();

        HasRequired(a => a.Person)
            .WithRequiredDependent();
    }
}

I don't know what I'm getting wrong, but EF:

What am I forgetting or doing wrong?

Upvotes: 0

Views: 51

Answers (2)

Fabio
Fabio

Reputation: 11990

You have to use WithRequired instead of WithOptionalPrincipal, and the relationship do not need to be configured in both sides.

public class PersonConfig : EntityTypeConfiguration<Person>
{
    public TaskConfig()
    {
        ToTable("tblPerson");

        HasKey(s => s.Id);

        Property(s => s.Id)
            .HasColumnName("idPerson");

        Property(s => s.Name)
            .HasColumnName("strName")
            .IsRequired();

        HasOptional(a => a.Car)
            .WithRequired(s => s.Person);
    }
}

public class CarConfig : EntityTypeConfiguration<Car>
{
    public CarConfig()
    {
        ToTable("tblCar");

        HasKey(s => s.PersonId)
            .Property(s => s.PersonId)
            .HasColumnName("idPerson");

        Property(s => s.Model)
            .HasColumnName("strModel")
            .IsRequired();

        //not necessary
        //HasRequired(a => a.Person)
            //.WithRequiredDependent();
    }
}

Upvotes: 1

Ivan Stoev
Ivan Stoev

Reputation: 205629

What am I forgetting or doing wrong?

You are not configuring the Person - Car relationship correctly.

Let fix that. Note that you don't need to configure the relationship in both places.

Remove the following from the Person config:

   HasOptional(a => a.Car)
        .WithOptionalPrincipal();

and replace the following in the Car config:

   HasRequired(a => a.Person)
        .WithRequiredDependent();

with

   HasRequired(c => c.Person)
        .WithOptional(p => p.Car);

Upvotes: 1

Related Questions