Guokas
Guokas

Reputation: 830

Entity Framework Core ForeignKey Default Conventions

I am looking for a document of [ForeignKey] conventions. I found a list of naming conventions on MSDN.

I am not sure which convention maps the below action.

class Student
{
    public int id{ set; get;}

    public int myclassroomid{ set; get;}

    public Classroom myclassroom{ set; get;}
}

class Classroom
{
    [Key]
    public int cid{ set; get;}
}

I don't understand how the default convention works.

I found the NavigationPropertyNameForeignKeyDiscoveryConvention, It does not seem to apply this scenario.

where can I found the official document? explain some main points if it has, it's would be better with a code example.

Upvotes: 1

Views: 278

Answers (2)

Ivan Stoev
Ivan Stoev

Reputation: 205629

You are looking at the wrong places - all these are for EF6, while EF Core is completely different system, so the starting point should be the official documentation here Entity Framework Core.

Foregn Key conventions are described in Relationships - Conventions, in particular:

If the dependent entity contains a property with a name matching one of these patterns then it will be configured as the foreign key:

  • <navigation property name><principal key property name>
  • <navigation property name>Id
  • <principal entity name><principal key property name>
  • <principal entity name>Id

In your example, myclassroomid is matching the rule #2 - navigation property name "myclassroom" + "Id". It's not mentioned explicitly but the matching is case insensitive, so "Id` also matches "ID", "id" etc.

Upvotes: 1

Steve Py
Steve Py

Reputation: 34793

The NavigationPropertyNameForeignKeyDiscoveryConvention covers how the navigation property in Student finds the FK declared in Student. AFAIK it wouldn't consider anything set up in the Classroom entity.

It will use the Type and reference name, so it would look for ClassroomId or MyClassroomId. This often trips up people which want to use multiple references to the same entity with one navigation property matching the type name. I.e. CustomerId/Customer Customer and CreatedById / Customer CreatedBy. EF may attempt to resolve CreatedBy to CustomerId based on the type.

The navigation property itself will marry up the reference to whatever field is declared as the PK in your Classroom type. Removing the [Key] attribute on cId in Classroom wouldn't work since that doesn't match the PK convention rules. (Id or ClassroomId) It also doesn't factor into FKs that way, I.e. placing a cId column in Student most likely wouldn't map through to the MyClassroom reference.

Personally I always use explicit mapping for relationships, and I avoid declaring FK properties, favoring shadow properties/Map() instead. If you're going to use conventions then your schema should be set up to conform to them without special cases. The easiest and most readable is to use {TableName}+Id for both the PK and FK references. The exception being multi-references to the same table/Entity, then using descriptive names for the references and their associated FKs. I.e. CreatedBy + CreatedById and OrderingCustomer + OrderingCustomerId instead of Customer + CustomerId if both navigation properties were to point at a Customer entity.

Upvotes: 1

Related Questions