Archive
Data Annotations – ForeignKey Attribute in EF 6 & EF Core
The ForeignKey attribute is used to configure a foreign key in the relationship between two entities in EF 6 and EF Core. It overrides the default conventions. As per the default convention, EF makes a property as foreign key property when its name matches with the primary key property of a related entity.
ForeignKey Signature: [ForeignKey(name string)]
- name: Name of the associated navigation property or the name of the associated foreign key(s).
Consider the following example of one-to-many relationship among entities.
public class Student { public int StudentID { get; set; } public string StudentName { get; set; } //Foreign key for Standard public int StandardId { get; set; } public Standard Standard { get; set; } } public class Standard { public int StandardId { get; set; } public string StandardName { get; set; } public ICollection<Student> Students { get; set; } }
The above example depicts a one-to-many relationship between Student
and Standard
entities. To represent this relationship, the Student
class includes a property StandardId
with reference property Standard
and Standard
entity class includes collection navigation property Students
. A property name StandardId
in Student
entity matches with the primary key property of Standard
entity, so StandardId
in Student
entity will automatically become a foreign key property and corresponding column in the db table will also be a foreign key column as shown below.

The [ForeignKey]
attribute overrides the default convention for a foreign key It allows us to specify the foreign key property in the dependent entity whose name does not match with the primary key property of the principal entity.
The [ForeignKey(name)]
attribute can be applied in three ways:
[ForeignKey(NavigationPropertyName)]
on the foreign key scalar property in the dependent entity[ForeignKey(ForeignKeyPropertyName)]
on the related reference navigation property in the dependent entity[ForeignKey(ForeignKeyPropertyName)]
on the navigation property in the principal entity
[ForeignKey] on the foreign key property in the dependent entity:
The [ForeignKey]
on the foreign key property in the dependent entity and the related navigation property name can be specified as a parameter as shown below.
public class Student { public int StudentID { get; set; } public string StudentName { get; set; } [ForeignKey("Standard")] public int StandardRefId { get; set; } public Standard Standard { get; set; } } public class Standard { public int StandardId { get; set; } public string StandardName { get; set; } public ICollection<Student> Students { get; set; } }
In the above example, the [ForeignKey]
attribute is applied on the StandardRefId
and specified the name of the navigation property Standard
. This will create the foreign key column named StandardRefId
in the Students
table, preventing the generation of a StandardId
column in the database.

[ForeignKey] on the navigation property in the dependent entity:
The [ForeignKey]
attribute can be applied to the navigation property and the related foreign key property name can be specified as shown below.
public class Student { public int StudentID { get; set; } public string StudentName { get; set; } public int StandardRefId { get; set; } [ForeignKey("StandardRefId")] public Standard Standard { get; set; } } public class Standard { public int StandardId { get; set; } public string StandardName { get; set; } public ICollection<Student> Students { get; set; } }
In the above example, the [ForeignKey]
attribute is applied on the Standard
navigation property and specified the name of the foreign key property StandardRefId
. This will create the foreign key column named StandardRefId
in the Students
table, preventing the generation of a StandardId
column in the database.
[ForeignKey] on the navigation property in the principal entity:
The [ForeignKey]
attribute can be applied to the navigation property in the principal entity and the related foreign key property name can be specified in the dependent entity as shown below.
public class Student { public int StudentID { get; set; } public string StudentName { get; set; } public int StandardRefId { get; set; } public Standard Standard { get; set; } } public class Standard { public int StandardId { get; set; } public string StandardName { get; set; } [ForeignKey("StandardRefId")] public ICollection<Student> Students { get; set; } }
In the above example, the [ForeignKey]
attribute is applied on the Students
navigation property in the principal entity Standard
. This will create a foreign key column StandardRefId
in the Students
table in the database.
Hope this help !
EF code first – Model compatibility cannot be checked because the database does not contain model metadata
This suggests that migration table is out of sync (even if your data isn’t), and that’s been part of the db schema now (since 4.3 I think – under system tables).
There could be many reasons and ways to experience that error , but most of the time…
The problematic part is some combination of manually backing/restoring the full database with code changes alongside – I’m not entirely certain as to why always.
In short, even if Db-s are the same migration table data might not be – and hash comparison may fail (still full restore sounds like good enough – but you have ‘two sides’).
What works for me is to use
Update-Database -Script
That creates a script with a ‘migration difference’,
which you can manually apply as an SQL script on the target server database (and you should get the right migration table rows inserted etc.).
If that still doesn’t work – you can still do two things…
a) remove the migration table (target – under system tables) – as per http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-automatic-migrations-walkthrough.aspx comments in there – that should fail back to previous behavior and if you’re certain that your Db-s are the same – it’s just going to ‘trust you’,
b) as a last resort I used – make a Update-Database -Script of the full schema (e.g. by initializing an empty db which should force a ‘full script’),
find the INSERT INTO [__MigrationHistory] records,
just run those, insert them into the database,
and make sure that your databases – and code match,
that should make things run in sync again.
(disclaimer: this is not a bullet proof to work at all times, you may need to try a few things given your local scenarios – but should get you in sync)
Also this will work
I found the code will work by changing
static LaundryShopContext()
{
Database.SetInitializer<LaundryShopContext>(
new DropCreateDatabaseIfModelChanges<LaundryShopContext>());
}
into
static LaundryShopContext()
{
Database.SetInitializer<LaundryShopContext>(
new DropCreateDatabaseAlways<LaundryShopContext>());
}
Comments