Reputation: 6463
I'm creating a POCO model to use with entity framework code first CTP5. I'm using the <key()> decoration to make a property map to a PK column. But how can I define a PK on more then one column, and specifically, how can I control order of the columns in the index? Is it a result of the order of properties in the class?
Edit: look at @kara's answer for an updated solution.
Thanks!
Upvotes: 116
Views: 90581
Reputation: 21
In EF or EF Core, the Column Order attribute is not supported for specifying key order, so the best practice is to configure composite keys in the OnModelCreating method of your DbContext.
public class MyEntity
{
public int MyFirstKeyProperty { get; set; }
public int MySecondKeyProperty { get; set; }
public string MyThirdKeyProperty { get; set; }
// Other properties
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>()
.HasKey(e => new { e.MyFirstKeyProperty, e.MySecondKeyProperty, e.MyThirdKeyProperty });
base.OnModelCreating(modelBuilder);
}
Upvotes: 1
Reputation: 3455
In EF Core 7.0 a new attribute for classes [PrimaryKey]
was introduced.
Example:
[PrimaryKey(nameof(FirstName),nameof(LastName))]
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string SomeProperty { get; set; }
}
This way, you don't have to use the fluent-api again.
Upvotes: 15
Reputation: 177133
NOTE: As of 2019 this answer became non-valid for later EntityFramework versions.
You can specify the column order in the attributes, for instance:
public class MyEntity
{
[Key, Column(Order=0)]
public int MyFirstKeyProperty { get; set; }
[Key, Column(Order=1)]
public int MySecondKeyProperty { get; set; }
[Key, Column(Order=2)]
public string MyThirdKeyProperty { get; set; }
// other properties
}
If you are using the Find
method of a DbSet
you must take this order for the key parameters into account.
Upvotes: 172
Reputation: 11
Use as a anonymous object:
modelBuilder.Entity<UserExamAttemptQuestion>().ToTable("Users").HasKey(o => new { o.UserId, o.Username });
Upvotes: 1
Reputation: 7451
If, like me, you prefer to use a configuration file you can do that in this way (based on Manavi's example):
public class User
{
public int UserId { get; set; }
public string Username { get; set; }
}
public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
{
ToTable("Users");
HasKey(x => new {x.UserId, x.Username});
}
}
Obviously you have to add the configuration file to your context:
public class Ctp5Context : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new UserConfiguration());
}
}
Upvotes: 13
Reputation: 33206
To complete the correct answer submitted by Slauma, you can use the HasKey method to specify an order for composite primary keys as well:
public class User
{
public int UserId { get; set; }
public string Username { get; set; }
}
public class Ctp5Context : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasKey(u => new
{
u.UserId,
u.Username
});
}
}
Upvotes: 75