1

Why do we need to create a primitive type i.e. User_ID if I have to declare a foregin key name over reference navigational proeperty?

e.g.

    public class Sims
    {
        public int ID { get; set; }

        public int Users_ID { get; set; }
        [ForeignKey("Users_ID")]
        public Users Users { get; set; }
    }

Why do I need public int Users_ID { get; set; } in order to put only a foreign key attribute over the Users?

azure boy
  • 193
  • 8

2 Answers2

2

Because that's telling EF that the foreign key field to use to store the id of the linked "Users" record is named "Users_ID".
If you don't explicitly need to have that field available in your Sims Entity, then you can just leave it out altogether & you don't need to have the ForeignKey Attribute at all & EF will manage that for you behind the scenes.

Alternatively, you could name the foreign key field "UsersId" and it will assume that's the foreign key due to convention.

So any of these should be completely fine:

//no explicit foreign key
public class Sims
{
    public int ID { get; set; }
    public Users Users { get; set; }
}

//explicit foreign key but EF works it out via convention
public class Sims
{
    public int ID { get; set; }
    public int UsersId { get; set; }
    public Users Users { get; set; }
}

//explicitly named foreign key which is named differently from 
//convention so needs to be pointed at.  note nameof() operator
//which will give a compiler error should you rename it, so is
//better than a magic string
public class Sims
{
    public int ID { get; set; }

    [ForeignKey(nameof(Users))]
    public int MyUsersFkField { get; set; }        
    public Users Users { get; set; }
}

You can also add the attribute to the Users property and point it at the Id field.

An important note is that if you use a non-conventionally named FK property and don't specify the foreign key at all, then EF will create a FK UsersId Field in the underlying database and use that (but this won't be exposed in your model)

GPW
  • 2,528
  • 1
  • 10
  • 22
  • In short, if I only declare Userid in sims then it will create a foreign key column in sims table, correct ? So again, if I can name the property whatever I like it to be then why foreign key attribute which only gives the benefit of naming it yourway? – azure boy Jan 16 '19 at 11:29
  • 1
    No. Just declaring an int property named `UserId` *won't* create a foreign key. it'll only do so if you have a *Navigation Property* pointing at the `User` table. if you add this navigation property *without* a foreign key ID field, then the foreign key field itself will be in the database but will *not* be available directly in code - e.g. `thisSim.Users.Id` would get you that id, but `thisSim.UserId` won't compile. – GPW Jan 16 '19 at 11:35
  • 2
    Oh, and if you're asking 'What is the point?', then you're right - for a new build using code first you shouldn't ever need to specify foreign keys like this. Where this is *really* useful is when you're developing an EF model to use with a pre-existing database. I have a database where the primary keys (and therefore foreign keys for these tables) are almost universally `VARCHAR` fields, and named (usually) something like `NameCode`. These attributes allow me to specify the relationship between the entities properly, so are very useful for me. – GPW Jan 16 '19 at 11:38
  • @GPW I was looking for this comment rather than the answer. – ErTR Jul 09 '20 at 07:32
0

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.

In your case this will create the foreign key column named Users_ID in the Sims table, preventing the generation of a ID column in the database.

DevDotNet
  • 153
  • 8