The entity type 'Patient' requires a primary key to be defined means EF Core found no property it could use as the key: nothing called Id or PatientId, no [Key] attribute and no HasKey call. Mark the real key with [Key], configure it with HasKey, or rename it to Id, and the model builds.

Reach for HasNoKey, the option the message suggests, only for data you never insert or update through EF. Adding an instance of a keyless type threw Unable to track an instance of type 'DailyCount' because it does not have a primary key.

The error

Unhandled exception. System.InvalidOperationException: The entity type 'Patient' requires a primary key to be defined. If you intended to use a keyless entity type, call 'HasNoKey' in 'OnModelCreating'. For more information on keyless entity types, see https://go.microsoft.com/fwlink/?linkid=2141943.
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.ValidateNonNullPrimaryKeys(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Sqlite.Infrastructure.Internal.SqliteModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)

Why it happens

The first time a context is used, here by EnsureCreated(), EF Core builds the model from your classes and validates it; the stack trace runs from ModelSource.CreateModel into ModelValidator. Every entity type EF tracks needs a primary key, and the validator stops at the first one without. The entity looked like this:

public class Patient
{
    public string PatientNumber { get; set; } = "";
    public string FullName { get; set; } = "";
}

PatientNumber is a sensible key, but EF does not guess from meaning; it looks for names. To see exactly which names it accepts, the same check ran against thirteen small classes with EF Core 10.0.12, reading the key EF chose from the model:

  • Found: Id, ID and id; DoctorId on class Doctor; NurseID on class Nurse; Id with a private setter; a string Id; a Guid ShiftId on class Shift.
  • Not found, same error: Ward_Id on Ward; PatientId on a class named PatientRecord, because the prefix must be the class name; ClinicNumber; a public field Id; a get-only property Id { get; }.

The fix

public class Patient
{
    [Key]
    public string PatientNumber { get; set; } = "";
    public string FullName { get; set; } = "";
}

With using System.ComponentModel.DataAnnotations; at the top of the file, the program created the database, saved the patient and printed Patients in the database: 1. The fluent version, with no attribute on the class, worked the same way:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
        => modelBuilder.Entity<Patient>().HasKey(p => p.PatientNumber);

Use the attribute when you are happy to keep mapping details on the entity, and HasKey when you keep entity classes free of EF concerns. Renaming the property to Id also satisfies the convention, but only do it if a column called Id is what you actually want.

How it was reproduced

A console app from dotnet new console with Microsoft.EntityFrameworkCore.Sqlite 10.0.12, a ClinicDb context on a local SQLite file, one Patient entity keyed by PatientNumber with no configuration, and db.Database.EnsureCreated() as the first call. The naming check built one context per class so that one failure could not hide another. .NET SDK 10.0.401, runtime 10.0.12, Windows 11.

Frequently asked

How do I fix The entity type requires a primary key to be defined?
Tell EF Core which property is the key: put [Key] on it, call modelBuilder.Entity<T>().HasKey(x => x.YourKey) in OnModelCreating, or name the property Id or the class name followed by Id so the convention finds it.
Does EF Core recognise Id in any letter case?
In a test with EF Core 10.0.12, Id, ID and id were all found, and so were DoctorId and NurseID on classes named Doctor and Nurse. Ward_Id, and PatientId on a class named PatientRecord, were not.
When should I use HasNoKey in EF Core?
Only for data you read but never insert, update or delete through EF. EF cannot track a keyless entity: adding one throws Unable to track an instance because it does not have a primary key.

More decoded errors in the Fixes category. Unsure whether a natural value like a patient number should be the key at all? See Primary Keys: Identity, GUID or Natural Key?