ForeignKey Attribute in Entity Framework

ForeignKey Attribute in Entity Framework

In this article, I am going to discuss ForeignKey Data Annotation Attribute in Entity Framework Code First Approach with Examples. Please read our previous article where we discussed Key Attributes in Entity Framework Code First Approach with Examples. Before understanding ForeignKey Attribute, let us first understand what is a Foreign Key in a database.

What is a Foreign Key Constraint in a Database?

One of the most important concepts in a database is creating the relationship between the database tables. This relationship provides a mechanism for linking the data stores in multiple database tables and retrieving them in an efficient manner.

In order to create a link between two database tables, we must specify a Foreign Key in one table that references a unique column (Primary Key or Foreign Key) in another table. That means the Foreign Key constraint is used for binding two database tables with each other and then verifying the existence of one table’s data in other tables. A foreign key in one TABLE points to a primary key or unique key in another table.

ForeignKey Attribute in Entity Framework:

The ForeignKey Attribute in Entity Framework is used to configure a Foreign Key Relationship between the two entities. It overrides the default Foreign Key convention which is followed by Entity Framework. As per the default convention, the Entity Framework API will look for the Foreign Key Property with the same name as the Principal Entity Primary Key Property name in the Dependent Entity.

A Relationship in Entity Framework always has two endpoints. Each endpoint must return a navigational property that maps to the other end of the relationship. Let us understand this with an example. The following Standard Entity is going to be our Principal Entity and StandardId is the Primary Key Property. Here, you can see, we have one collection navigational property i.e. students and this is mandatory in order to implement Foreign Key Relationships using Entity Framework Code First Approach.

using System;
using System.Collections.Generic;
namespace EFCodeFirstDemo
{
    public class Standard
    {
        public int StandardId { get; set; }
        public string StandardName { get; set; }
        public string Description { get; set; }
        public ICollection<Student> Students { get; set; }
    }
}

Now, modify the Student Entity as follows. Here, you can see, we have added the StandardId property whose name is the same as the Primary Key Property of the Standard table. We have also added the Standard Reference Navigational Property and this is mandatory.

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EFCodeFirstDemo
{
    public class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        //The Following Property Exists in the Standard Entity
        public int StandardId { get; set; }

        //To Create a Foreign Key it should have the Standard Navigational Property
        public Standard Standard { get; set; }
    }
}

Note: The point that you need to remember, both Entities should and must have Navigational Properties to implement Foreign Key Relationships. In our example, Student Entity has the Standard Reference Navigational Property, and Standard Entity has the Students collection Navigation Property which will establish the one-to-many relationship between these two entities. That means one student has one standard and one standard can have multiple students.

As we are going to update the Entity Models many times, in order to avoid the Run Time Exception when the model changes and when we rerun the application, let us set the database initializer as DropCreateDatabaseIfModelChanges. So, modify the context class as follows:

using System.Data.Entity;
namespace EFCodeFirstDemo
{
    public class EFCodeFirstContext : DbContext
    {
        public EFCodeFirstContext() : base("name=MyConnectionString")
        {
            //Setting the Database Initializer as DropCreateDatabaseIfModelChanges
            Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EFCodeFirstContext>());
        }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
        }
        public DbSet<Student> Students { get; set; }
        public DbSet<Standard> Standards { get; set; }
    }
} 

Please make sure to have the connection string with the name MyConnectionString within the app.config file or web.config file as shown in the below image.

ForeignKey Data Annotation Attribute in Entity Framework Code First Approach with Examples

Now, modify the Main method of the Program class as follows. Here, we are adding one standard and student entity into the database.

using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection;
using System;
namespace EFCodeFirstDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            using (EFCodeFirstContext context = new EFCodeFirstContext())
            {
                var standard = new Standard()
                {
                    StandardName = "First",
                    Description = "First Standard"
                };
                context.Standards.Add(standard);
                context.SaveChanges();

                var student = new Student() { FirstName = "Pranaya", LastName = "Rout", StandardId= standard.StandardId };
                context.Students.Add(student);
                context.SaveChanges();
                Console.WriteLine("Student Added");
                Console.ReadKey();
            }
        }
    }
}

In our example, it will represent the one-to-many relationship between the Student and Standard Entities. To represent this relationship, the Student class includes a property StandardId with reference property Standard, and the Standard entity class includes a collection navigation property Students. A property name StandardId in Student Class matches with the primary key property of Standard class, so the StandardId Property in Student class will automatically become a foreign key property and the corresponding column in the database table will also become a foreign key column.

Now, run the above application code and verify the database, the Foreign key should have been created in the Student database as shown in the below image. Here, you can see the Foreign Key Property is created with the name StudentId.

ForeignKey Attribute in Entity Framework

If the Foreign Key Property does not exist in the Dependent Entity class, then Entity Framework will create a Foreign Key column in the Database table with <Dependent Navigation Property Name> + “_” + <Principal Entity Primary Key Property Name>. To understand this, modify the Student Entity class as follows. Here, you can see, we have not added the StandardId property. So, in this case, Entity Framework will create the Foreign Key with the name <Dependent Navigation Property Name> + “_” + <Principal Entity Primary Key Property Name> i.e. Standard_StandardId. We must have added the Standard Property, otherwise, the foreign key will not be created.

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EFCodeFirstDemo
{
    public class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        //To Create a Foreign Key it should have the Standard Navigational Property
        public Standard Standard { get; set; }
    }
}

Now, modify the Main method as follows to remove the compile time error.

using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection;
using System;
namespace EFCodeFirstDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            using (EFCodeFirstContext context = new EFCodeFirstContext())
            {
                var student = new Student() { FirstName = "Pranaya", LastName = "Rout"};
                context.Students.Add(student);
                context.SaveChanges();
                Console.WriteLine("Student Added");
                Console.ReadKey();
            }
        }
    }
}

Now, with the above changes in place, run the above application code and verify the database, and the Foreign key should have been created in the Student database table as shown in the below image. Here, you can see the Foreign Key Property is created with the name Standard_StandardId.

What is ForeignKey Attribute in Entity Framework?

These are the default conventions which is followed by Entity Framework to create the Foreign Key column in the database.

What is ForeignKey Attribute in Entity Framework?

The ForeignKey Attribute in Entity Framework is used to configure a foreign key relationship between the entities. It overrides the default foreign key convention which is followed by Entity Framework. It allows us to specify the foreign key property in the dependent entity whose name does not match the primary key property of the principal entity. Now, if you go to the definition of ForeignKey Attribute, then you will see the following. As you can see, this class has one constructor which takes the name of the associated navigation property or the name of one or more associated foreign keys as an input parameter.

ForeignKey Attribute in Entity Framework

The [ForeignKey(name)] attribute can be applied in three ways:

  1. [ForeignKey(NavigationPropertyName)] on the foreign key scalar property in the dependent entity.
  2. [ForeignKey(ForeignKeyPropertyName)] on the related reference navigation property in the dependent entity.
  3. [ForeignKey(ForeignKeyPropertyName)] on the navigation property in the principal entity.

Note: Before proceeding further, first of all, we need to identify which is Principal Entity and which is the Dependent Entity. In our example, Standard is the Principal Entity and Student is the Dependent Entity and in the Dependent Entity, we are going to create the Foreign Key.

[ForeignKey] on the Foreign Key Property in the Dependent Entity

The [ForeignKey] Attribute in Entity Framework can be applied to the foreign key property in the Dependent Entity and the related navigation property name (in this case Standard) can be specified as a parameter. For a better understanding, please modify the Student Entity as follows.

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EFCodeFirstDemo
{
    public class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        [ForeignKey("Standard")]
        public Nullable<int> StandardReferenceId { get; set; }

        //Related Standard Navigational Property
        public Standard Standard { get; set; }
    }
}

In the above example, the [ForeignKey] attribute is applied on the StandardReferenceId property and specified the navigation property name i.e. Standard. In this case, Entity Framework will create the Foreign Key column StandardReferenceId in the Students database table as shown in the below image.

[ForeignKey] on the Foreign Key Property in the Dependent Entity

[ForeignKey] on the Navigation Property in the Dependent Entity

The [ForeignKey] Attribute in Entity Framework can also be applied to the Navigation Property and in this case, we need to specify the related foreign key property name in the [ForeignKey] Attribute. For a better understanding, please modify the Student Entity as follows.

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EFCodeFirstDemo
{
    public class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        //Related Foreign Key Property
        public Nullable<int> StandardReferenceId { get; set; }
        
        [ForeignKey("StandardReferenceId")]
        public Standard Standard { get; set; }
    }
}

In the above example, the [ForeignKey] attribute is applied on the Standard navigation property and the name of the foreign key property StandardReferenceId is specified. Here, Entity Framework will create the foreign key column StandardReferenceId in the Students table in the database as shown in the below image when you run the application.

[ForeignKey] on the Navigation Property in the Dependent Entity

[ForeignKey] on the Navigation Property in the Principal Entity

The [ForeignKey] Attribute in Entity Framework can also be applied to the Navigation Property in the Principal Entity and the related foreign key property name can be specified in the Dependent Entity. Let us understand this with an example. First, modify the Student Entity as follows. Here, you can see we have removed the ForeignKey Attribute.

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EFCodeFirstDemo
{
    public class Student
    {
        public int StudentId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        
        public Nullable<int> StandardReferenceId { get; set; }
        public Standard Standard { get; set; }
    }
}

Now, we want the Property StandardReferenceId to be created as a Foreign Key column in the database which must be pointed to the StandardId Property of the Standard entity. To do so, modify the Standard Entity as follows. Here, you can see, the [ForeignKey] attribute is applied on the Students collection navigation property and here we are passing the StandardReferenceId property to the [ForeignKey] attribute and this will make the StandardReferenceId as a Foreign Key Property.

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace EFCodeFirstDemo
{
    public class Standard
    {
        public int StandardId { get; set; }
        public string StandardName { get; set; }
        public string Description { get; set; }

        [ForeignKey("StandardReferenceId")]
        public ICollection<Student> Students { get; set; }
    }
}

Now, run the application code and verify the database and check the Students database table, and you should see the StandardReferenceId column as the Foreign Key column as shown in the below image.

[ForeignKey] on the Navigation Property in the Principal Entity

Note: In our upcoming articles, I am going to discuss One-to-One, One-to-Many, and Many-to-Many Relationships in detail using Entity Framework Code First Approach.

In the next article, I am going to discuss Index Attributes in Entity Framework Code First Approach with Examples. Here, in this article, I try to explain ForeignKey Data Annotation Attribute in Entity Framework Code First Approach with Examples. I hope you enjoyed this ForeignKey Attribute in Entity Framework Code First Approach with Examples article. Please give your valuable feedback and suggestions about this article.

Leave a Reply

Your email address will not be published. Required fields are marked *