C# EF Code First 5-如何使用Fluent API定义可为空的外键?

C# EF Code First 5-如何使用Fluent API定义可为空的外键?,c#,entity-framework-5,fluent,C#,Entity Framework 5,Fluent,我有两张桌子- 1. Account 2. Users 在Account表中,DefaultExpensePartner和AccountOwner是Users表的UserId字段的外键。我对类的定义如下 public class Account { public int AccountId { get; set; } public string AccountName { get; set; } public int? AccountOwnerId { get;

我有两张桌子-

 1. Account 

 2. Users
Account
表中,
DefaultExpensePartner
AccountOwner
Users
表的
UserId
字段的外键。我对类的定义如下

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();
    }
}
公共类帐户
{
public int AccountId{get;set;}
公共字符串AccountName{get;set;}
public int?AccountOwnerId{get;set;}
public int?DefaultExpensePartnerId{get;set;}
公共虚拟用户帐户所有者{get;set;}
公共虚拟用户DefaultExpensePartner{get;set;}
}
公共类AccountConfiguration:EntityTypeConfiguration
{
公共帐户配置()
{
本表为可转帐(“账户”);
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(“账户所有者”)
.等民族();
this.Property(c=>c.DefaultExpensePartnerId)
.HasColumnName(“DefaultExpensePartner”)
.等民族();
this.HasRequired(c=>c.DefaultExpensePartner)
.有很多
.HasForeignKey(c=>c.DefaultExpensePartnerId)
.WillCascadeOnDelete(假);
this.HasRequired(c=>c.AccountOwner)
.有很多
.HasForeignKey(c=>c.AccountOwnerId)
.WillCascadeOnDelete(假);
}
}
公共类用户
{
public int UserId{get;set;}
公共字符串电子邮件{get;set;}
公共字符串DisplayName{get;set;}
公共字符串密码salt1{get;set;}
公共字符串密码salt2{get;set;}
公共字符串密码哈希{get;set;}
}
公共类用户配置:EntityTypeConfiguration
{
公共用户配置()
{
本表为ToTable(“用户”);
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();
}
}

虽然我能够为
AccountOwner
DefaultExpensePartner
字段建立外键关系,但它们在数据库中被定义为非空,根据我的原始计划,这是不正确的。任何人都知道如何将外键定义为可空的吗?

除非您真的愿意,否则不必指定key属性,这有点像是先编写代码:)

根据需要,删除外键属性就足够了。看看本文中图1和图2之间的差异。(密钥当然会在数据库级别生成,但您真的需要模型中的密钥吗?

如果您希望具有可为空的外键,为什么要按需要定义它:

?

改用
has可选

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

我已经尝试过使用HasOptional,但它没有改变结构中的任何内容。我不知道有哪些不同的术语用于相同的功能。看起来他们在前端的行为可能会有所不同。有人能帮我解决这个相关的问题吗。当然,我在模型中需要这个,因为这是它在数据库中应该是怎样的。我仍在寻找解决办法-(哦,我忘了回答,我想你是对的。不可能添加可为空的外键,没有外键也是有意义的。我重新设计了数据库结构,现在一切都很好。有人能帮我解决这个相关问题吗。
        this.HasOptional(c => c.AccountOwner)
            .WithMany()
            .HasForeignKey(c => c.AccountOwnerId)
            .WillCascadeOnDelete(false);