Gaining Some Control Back From Microsoft’s Entity Framework Code First, Name Your Own Foreign Keys!

Being a relative newbie to Microsoft’s Entity Framework Code First, there are things that I don’t like, things that I don’t understand, and well, just things that really bug me.  The problem is I often find out that the things that I don’t like and bug me are often lack of knowledge and not lack of product (at least not easily discoverable in the product).  One of those things is that Code First makes up names for foreign keys that don’t happen to be the same name as I would use.  Since there are times when you will need to look at these names (and possibly code with them (for another post)), I would like those names to be my names.

Let’s say you have a simple relationship between two tables.  Let’s call it User and Address.  Let’s just say for simplicity a user has one address.  In CodeFirst, you would model it with tables like the following:

public class User
{
        [Key] 
        public long Id { get; set; }
        public virtual Address Address { get; set; } 
       // more details about user, name, etc.
}

public class Address
{
       [Key] 
        public long Id { get; set; }
        public string City {get;set;}
        // more details about address, state,zip,etc.
}

Now, you will end up with an Address table that has a column named something like User_Id.   YUC!!!  Who puts underscores in column names anymore (well, certainly I don’t.

You may think all you need to do to solve this is put a foreign key column and attribute in the Address table as follows:

public class Address
{
     [Key]
     public long Id {get;set;}
     
     [ForeignKey]
     public long UserId {get;set;}

     public string City {get;set;}
}

But, when you do that, you will be greeted with an error that looks like the following:

System.Data.Entity.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role ‘EmailAccount_User_Source’ in relationship ‘EmailAccount_User’. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be ‘*’.

or

The ForeignKeyAttribute on property ‘UserId’ on type ‘EFCodeFirstLib.CodeFirstModels.EmailAccount’ is not valid. The navigation property ‘User’ was not found on the dependent type ‘EFCodeFirstLib.CodeFirstModels.EmailAccount’. The Name value should be a valid navigation property name.

 

Pretty clear what to do, huh?

Well, I suppose if you know EF EDMX and a whole bunch of other acronyms, you probably will figure it out, but if you don’t I’ll tell you.  You basically need to include the User property in your Address class.  It should then look like:

public class Address
{
  [Key]
  public long Id {get;set}

  public User User {get;set;}  // important!
  [ForeignKey]
  public long UserId {get;set;}

  public string City {get;set;}
}

And now, you will have a “properly” named foreign key column “UserId” with no underscores!

My 2Cents.

About Peter Kellner

Peter is a software professional specializing in mobile and web technologies. He has also been a Microsoft MVP for the past 7 years. To read more about Peter Kellner and his experience click here. For information about how Peter Kellner might be able to help you with your project click here.

Follow me:


Comments

  1. huri jin says:

    Your code does not compile.
    error CS1729: ‘System.ComponentModel.DataAnnotations.Schema.ForeignKeyAttribute’ does not contain a constructor that takes 0 arguments

Your Comments

*

Protected with IP Blacklist CloudIP Blacklist Cloud

Follow

Get every new post delivered to your Inbox

Join other followers: