Ankit
Ankit

Reputation: 2518

Getting error when doing Enable-Migrations in Entity Framework Code First

I am trying to create 1:many relationship between Person and Car. I know this is trivial. But on passing a Enable-Migrations in package manager console i am getting this:

Car_Person_Target_Car_Person_Source: : The types of all properties in the Dependent Role of a referential constraint must be the same as the corresponding property types in the Principal Role. The type of property 'PersonID' on entity 'Car' does not match the type of property 'FirstName' on entity 'Person' in the referential constraint 'Car_Person'.

Car_Person_Target_Car_Person_Source: : The types of all properties in the Dependent Role of a referential constraint must be the same as the corresponding property types in the Principal Role. The type of property 'PersonSsn' on entity 'Car' does not match the type of property 'LastName' on entity 'Person' in the referential constraint 'Car_Person'.

Person Class:

public class Person
{
    public Person()
    {
        Cars = new List<Car>();
    }
        [Key, Column(Order = 0)]
        public int ID { get; set; }
        [Key, Column(Order = 1)]
        public int Ssn { get; set; }
        public int Age { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public virtual ICollection<Car> Cars { get; set; }  
}

Car class:

public class Car
{        
    [Key, Column(Order = 0)]
    public int ID { get; set; }
    [Key, Column(Order = 1)]
    public int ChassisSerial { get; set; }

    [ForeignKey("Person"), Column(Order = 0)]
    public int? PersonID { get; set; }
    [ForeignKey("Person"), Column(Order = 1)]
    public int? PersonSsn { get; set; }

    public virtual Person Person { get; set; }
}

Thanks in advance.

Upvotes: 1

Views: 2051

Answers (3)

Ankit
Ankit

Reputation: 2518

I found the issue when looked at the context class.

The issue was due to already existing composite key FirstName-LastName defined in context class using both car and person as DbSet.

Car_Person_Target_Car_Person_Source: : The types of all properties in the Dependent Role of a referential constraint must be the same as the corresponding property types in the Principal Role. The type of property 'PersonSsn' on entity 'Car' does not match the type of property LastName on entity 'Person' in the referential constraint 'Car_Person'.

Upvotes: 0

Pedro Benevides
Pedro Benevides

Reputation: 1974

If you are using composite key, you should use Fluent API from Entity Framework, to configure the relationships. For example:

Person Configuration

public class PersonEntityTypeConfiguration : EntityTypeConfiguration<Person>
{
    public PersonEntityTypeConfiguration()
    {
        HasKey(t => new { t.ID, t.Ssn });
        Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }
}

Car Configuration

public class CarEntityTypeConfiguration : EntityTypeConfiguration<Car>
{
    public CarEntityTypeConfiguration()
    {
        HasKey(t => new { t.ID, t.ChassisSerial });
        Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        HasOptional(t => t.Person).WithMany().HasForeignKey(t => new { t.PersonID, t.PersonSsn });
    }
}

And in your Context class, you register in OnModelCreating

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{ 
    modelBuilder.Configurations.Add(new PersonEntityTypeConfiguration());
    modelBuilder.Configurations.Add(new CarEntityTypeConfiguration());

    base.OnModelCreating(modelBuilder);
}

Upvotes: 1

Scharly Ochoa
Scharly Ochoa

Reputation: 301

Change the type of the foreign keys to "int", they must match with Person's PK type

public class Car
{        
    [Key, Column(Order = 0)]
    public int ID { get; set; }
    [Key, Column(Order = 1)]
    public int ChassisSerial { get; set; }

    [ForeignKey("Person"), Column(Order = 0)]
    public int PersonID { get; set; }
    [ForeignKey("Person"), Column(Order = 1)]
    public int PersonSsn { get; set; }

    public virtual Person Person { get; set; }
}

Upvotes: 3

Related Questions