System.InvalidOperationException: Unable to determine the relationship represented by navigation 'Customer.Orders' of type 'List<Order>'. — Order had two navigations back to Customer (Buyer and Seller), and Customer.Orders could pair with either. Say which one with [InverseProperty(nameof(Order.Buyer))] on Orders.

The message itself offers two ways out: configure the relationship, or ignore the property with [NotMapped] or Ignore. When the collection is meant to hold data, configuring it is the one you want; the attribute below is the shortest form.

The error

PS> dotnet run
Unhandled exception. System.InvalidOperationException: Unable to determine the relationship represented by navigation 'Customer.Orders' of type 'List<Order>'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.ValidatePropertyMapping(IConventionTypeBase structuralType, IConventionModel model, IDiagnosticsLogger`1 logger)
...
   at Program.<Main>$(String[] args) in ...\EfRel\Program.cs:line 5

The cut hides EF Core and DI frames. Line 5 is db.Database.EnsureDeleted(), the first call that needed the model, and the top frame is ModelValidator: the model was rejected before any SQL ran.

Why it happens

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; } = "";
    public List<Order> Orders { get; set; } = [];
}

public class Order
{
    public int Id { get; set; }
    public Customer Buyer { get; set; } = null!;
    public Customer Seller { get; set; } = null!;
}

An order has a buyer and a seller, both customers. Customer.Orders is a collection of orders, but nothing in the classes says whether it lists the orders a customer bought or the ones they sold. In this run EF Core rejected the model and named the navigation it could not place.

The message names only one side: Customer.Orders, class first, and its declared type List<Order>. Buyer and Seller do not appear in it, so the competing navigations have to be found by opening the class the collection points to, here Order, and looking for every property of type Customer.

The fix

    [InverseProperty(nameof(Order.Buyer))]
    public List<Order> Orders { get; set; } = [];
PS> dotnet run -p:DefineConstants=FIXED
Maria Garcia bought 1 order(s)

The attribute (from System.ComponentModel.DataAnnotations.Schema) pairs Customer.Orders with Order.Buyer. In the lab both versions sit in one file behind #if FIXED, and -p:DefineConstants=FIXED compiles the attribute in. With it, the program created the database, saved one order with Maria Garcia as buyer and David Chen as seller, and loaded Maria with Include(c => c.Orders): one order. Seller stayed a navigation without a collection on the other side, and the model accepted that.

How it was reproduced

A console project from dotnet new console -n EfRel on .NET SDK 10.0.403 with Microsoft.EntityFrameworkCore.Sqlite 10.0.14 and a SQLite file shop.db. dotnet run without the attribute threw at the first database call; dotnet run -p:DefineConstants=FIXED printed the order count. The two customers are fictional.

Frequently asked

What does Unable to determine the relationship represented by navigation mean?
EF Core could not decide which navigation on the other entity a collection or reference pairs with. In the reproduction Order had two Customer navigations, Buyer and Seller, and Customer.Orders matched both.
How do I fix Unable to determine the relationship with InverseProperty?
Put [InverseProperty(nameof(Order.Buyer))] on the collection, naming the navigation on the other class it belongs to. In the reproduction that alone made the model valid.
When does EF Core throw Unable to determine the relationship?
In the reproduction it was thrown by ModelValidator at the first database call, EnsureDeleted, before any SQL ran.

More decoded errors in the Fixes category.