0

I try to model many to many relationship between Car and Employee where the info about when the car was used are held. So I need a class inbetween which will hold those additional attributes.

The SSCCE:

I have Person class:

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

and a class Employee which derives from Person:

public class Employee : Person {
      public virtual ICollection<EmployeeCar> EmployeeCar { get; set; }
}

and a association classEmployeeCar which holds attributes dateFrom, dateTo:

public class EmployeeCar {
    [Key, Column(Order = 0)]
    public virtual Car Car { get; set; } 
    [Key, Column(Order = 1)]
    public virtual Employee Employee { get; set; }

    public DateTime DateFrom{ get; set; }
    public DateTime DateTo { get; set; }
}  

and finally class Car:

public class Car {
        public int Id { get; set; }
        public virtual ICollection<EmployeeCar>  EmployeeCar { get; set; }
    }

in ApplicationDbContext I hold:

    public DbSet<Person> Persons { get; set; }
    public DbSet<EmployeeCar> EmployeesCars { get; set; }
    public DbSet<Car> Cars { get; set; }

but when I run the database-update I get:

MyApp.EmployeeCar: : EntityType 'EmployeeCar' has no key defined. Define the key for this EntityType.
EmployeesCars: EntityType: EntitySet 'EmployeesCars' is based on type 'EmployeeCar' that has no keys defined.

How to fix that situation? How to tell Entity Framework that combination of Car and Employee is the key?

Yoda
  • 17,363
  • 67
  • 204
  • 344

1 Answers1

1

You would need to add the ID properties themselves to the model definition -- EF can add foreign key properties automatically, but it probably doesn't like the idea of seeing navigation properties as keys.

public class EmployeeCar {
    [Key, Column(Order = 0)]
    public int CarId { get; set; }
    [Key, Column(Order = 1)]
    public int EmployeeId { get; set; }

    public virtual Car Car { get; set; }
    public virtual Employee Employee { get; set; }

    public DateTime DateFrom{ get; set; }
    public DateTime DateTo { get; set; }
}  

Create code first, many to many, with additional fields in association table

Community
  • 1
  • 1
jjj
  • 4,822
  • 1
  • 16
  • 39
  • Unfotunately I got: `The object 'PK_dbo.EmployeeCar' is dependent on column 'EmployeeId'. The object 'FK_dbo.Person_dbo.EmployeeCar_EmployeeCar_CarId_EmployeeCar_EmployeeId' is dependent on column 'EmployeeId'. ALTER TABLE DROP COLUMN EmployeeId failed because one or more objects access this column. PM> ` – Yoda Jun 01 '15 at 19:16
  • Automatic migrations? The message makes it sounds like you did have a key at some point – jjj Jun 01 '15 at 20:32
  • @yoda: yeah I'm not sure why it would try to drop that column – jjj Jun 01 '15 at 23:19
  • I changed the connection name so it deployed new database and it went fine this time. Is this is the shortest way to solve that problem? I mean: `[Key, Column(Order = 0)] public int CarId { get; set; } [Key, Column(Order = 1)] public int EmployeeId { get; set; }`? – Yoda Jun 02 '15 at 05:58
  • For a many-to-many join table like this with additional properties, the only other way I can think of is to use fluent API. This is definitely more concise (though whether it's preferable depends on your design philosophy). I'm not sure if there are other ways – jjj Jun 02 '15 at 06:51