Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Code First 5 - How to define nullable foreign key using Fluent API?

I have two table -

 1. Account 

 2. Users

In Account table, DefaultExpensePartner and AccountOwner are foreign key of UserId field of Users table. I have defined classes as below.

public class Account
{
    public int AccountId { get; set; }
    public string AccountName { get; set; }
    public int? AccountOwnerId { get; set; }
    public int? DefaultExpensePartnerId { get; set; }

    public virtual Users AccountOwner { get; set; }
    public virtual Users DefaultExpensePartner { get; set; }
}

public class AccountConfiguration : EntityTypeConfiguration<Account>
{
    public AccountConfiguration()
    {
        this.ToTable("Account");

        this.HasKey(c => c.AccountId);

        this.Property(c => c.AccountId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
            .IsRequired();

        this.Property(c => c.AccountName)
            .HasMaxLength(50)
            .IsRequired();

        this.Property(c => c.AccountOwnerId)
            .HasColumnName("AccountOwner")
            .IsOptional();

        this.Property(c => c.DefaultExpensePartnerId)
            .HasColumnName("DefaultExpensePartner")
            .IsOptional();

        this.HasRequired(c => c.DefaultExpensePartner)
            .WithMany()
            .HasForeignKey(c => c.DefaultExpensePartnerId)
            .WillCascadeOnDelete(false);

        this.HasRequired(c => c.AccountOwner)
           .WithMany()
           .HasForeignKey(c => c.AccountOwnerId)
           .WillCascadeOnDelete(false);
    }
}

public class Users
{
    public int UserId { get; set; }
    public string Email { get; set; }
    public string DisplayName { get; set; }
    public string PasswordSalt1 { get; set; }
    public string PasswordSalt2 { get; set; }
    public string PasswordHash { get; set; }
}

public class UsersConfiguration : EntityTypeConfiguration<Users>
{
    public UsersConfiguration()
    {
        this.ToTable("Users");

        this.HasKey(c => c.UserId);

        this.Property(c => c.UserId)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
            .IsRequired();

        this.Property(c => c.Email)
            .HasMaxLength(80)
            .IsRequired();

        this.Property(c => c.DisplayName)
            .HasMaxLength(50)
            .IsRequired();

        this.Property(c => c.PasswordSalt1)
            .HasMaxLength(172)
            .IsRequired();

        this.Property(c => c.PasswordSalt2)
            .HasMaxLength(172)
            .IsRequired();

        this.Property(c => c.PasswordHash)
            .HasMaxLength(40)
            .IsRequired();
    }
}

Though I am able to establish foreign key relationship for AccountOwner and DefaultExpensePartner fields, they are defined as non-null in database which is incorrect according to my original plan. Can anyone know how to define foreign key as nullable?

like image 986
Parth Patel Avatar asked Jan 16 '13 13:01

Parth Patel


People also ask

How do I add a foreign key in Fluent API?

You can then configure foreign key properties by using the HasForeignKey method. This method takes a lambda expression that represents the property to be used as the foreign key.

How do you define a foreign key in Entity Framework code First?

To create Foreign Key, you need to use ForeignKey attribute with specifying the name of the property as parameter. You also need to specify the name of the table which is going to participate in relationship.

Can a foreign key be null EF core?

A foreign key is NULLABLE by DEFAULT in code first asp.net mvc - 5 entity framework. If we want to make it non nullable. we need to either use fluent api if not then decorate with "Required" attribute.

How do you configure a primary key for an entity in Entity Framework Fluent API?

Configuring a primary key By convention, a property named Id or <type name>Id will be configured as the primary key of an entity. Owned entity types use different rules to define keys. You can configure a single property to be the primary key of an entity as follows: Data Annotations.


2 Answers

If you want to have nullable foreign key, why are you defining it as required:

this.HasRequired

?

Use HasOptional instead:

        this.HasOptional(c => c.AccountOwner)
            .WithMany()
            .HasForeignKey(c => c.AccountOwnerId)
            .WillCascadeOnDelete(false);
like image 145
Dennis Avatar answered Oct 07 '22 09:10

Dennis


You do not have to specify the key-property unless you really want to, which is kinda the idea of code first :)

According to this article by Microsoft it should be enough to remove the foreign key properties. Have a look at the differences between figure 1 and figure 2 in the article. (The keys will of course be generated at the database level, but do you really need them in the model?)

like image 30
flindeberg Avatar answered Oct 07 '22 08:10

flindeberg