(EF Core) Specifying Primary Key (s) and the DbSet.Find() method

This is a brief explanation of how to specify single primary key on a model through attributes - but this approach fails when multiple columns are to be set as the primary key. We explain that such a composite primary key has to be set through the DbContext. Finally, we explain how to query a record on the basis of its primary key.

Categories | About |     |  

Parveen,

How to specify a Single Primary Key

A single primary key can be specified by using the [Key] attribute as shown below.

public class Product
{

  // auto-increment Primary ID key 
  [Key]
  [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  public int ID { get; set; }

  // a short code 
  public int ShortCode { get; set; }

  // any other property 
  [Required]
  public String Name { get; set; }
}

Video Explanation

Please watch the following youtube video:

How to specify a Composite Primary Key

Let us suppose we want a composite primary key of ID and ShortCode in the model below.

// EF Core doesn't allow composite primary 
// keys to be set through attributes 
// so we have to set that in the ProductContext 
// as done later 
public class Product
{

  // should be the first primary key 
  public int ID { get; set; }

  // short code second primary key 
  public int ShortCode { get; set; }

  // any other property 
  [Required]
  public String Name { get; set; }
}

The composite key is set on the OnModelCreating method as can be seen below.

// dbcontext DAL - THERE IS ONE DbContext per database 
public class ProductContext : DbContext
{

  public ProductContext(DbContextOptions options) : base(options)
  {

    // EnsureCreated is meant for testing or creating 
    // a blank database. this code should be avoided 
    // at this place. use some alternate program to 
    // create/migrate your database. this code has been 
    // used here only for tutorial purposes 
    Database.EnsureCreated();

  }

  // this function is used to specify FK relations, Indexes, 
  // and [optionally] the name of your database tables 
  // corresponding to each model 
  protected override void OnModelCreating(ModelBuilder modelBuilder)
  {

    base.OnModelCreating(modelBuilder);

    // name of the table in your database 
    // also composite PK 
    // also an optional name of the PK 
    modelBuilder.Entity<Product>()
    .ToTable("product")
    .HasKey(k => new { k.ID, k.ShortCode })
    .HasName("PK_IDSCode");


    // we were not able to mark ID and/or ShortCode 
    // to identity auto-increment type 
  }

  // MUST be PLURAL 
  public DbSet<Product> Products { get; set; }
}

How to find a record based on Primary Key(s)

We have to use the Find() or FindAsync() method to specify an array of primary key values in the same order as defined in the OnModelCreating method.

// _ctx is ProductContext 
// the first parameter is ID and 
// the second ShortCode 
// the arguments MUST be the same 
// order as defined in OnModelCreating 
Product p = _ctx.Find<Product>(0, 3);


// p is null if not found 

This Blog Post/Article "(EF Core) Specifying Primary Key (s) and the DbSet.Find() method" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.

Comments and Discussion