【问题标题】:EF Code First 5 - How to define nullable foreign key using Fluent API?EF Code First 5 - 如何使用 Fluent API 定义可为空的外键?
【发布时间】:2013-01-16 13:09:48
【问题描述】:

我有两张桌子-

 1. Account 

 2. Users

Account表中,DefaultExpensePartnerAccountOwnerUsers表的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();
    }
}

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

【问题讨论】:

    标签: c# entity-framework-5 fluent


    【解决方案1】:

    如果你想拥有 nullable 外键,为什么要将它定义为必需

    this.HasRequired
    

    ?

    改用HasOptional

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

    【讨论】:

    • 我已经尝试过使用 HasOptional 但它不会改变结构中的任何内容。我不知道为什么不同的术语用于相同的功能。看起来他们在前端的行为可能会有所不同。
    • 有人可以帮我解决这个相关问题吗? stackoverflow.com/questions/45571025/…
    【解决方案2】:

    除非你真的想要,否则你不必指定键属性,这有点代码优先的想法:)

    根据this article by Microsoft 应该足以删除外键属性。看看文章中图1和图2的区别。 (密钥当然会在数据库级别生成,但模型中真的需要它们吗?)

    【讨论】:

    • 当然,我在模型中需要这个,因为这就是它应该在数据库中的样子。我仍在寻找解决方案。 :-(
    • 哦,我忘了回复,我认为你是对的。添加可为空的外键是不可能的,不这样做也是有道理的。我重新设计了数据库结构,现在一切都很好。
    • 有人可以帮我解决这个相关问题吗? stackoverflow.com/questions/45571025/…
    猜你喜欢
    • 2013-10-21
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    • 2015-08-08
    相关资源
    最近更新 更多