EF6 Code First:使用Fluent API声明外键

Ste*_*ash 4 c# entity-framework ef-code-first

我正在与EF 6和Code First合作开发一个与保险行业相关的应用程序.对于此应用程序,每个帐户可以有多个策略,每个策略可以有多个事务.此外,每个帐户必须与身份(姓名,地址,城市等)有关系.该策略还与Identity有关系,但它是可选的.

由于帐户 - >身份和帐户 - >>策略 - >身份,我发现我需要使用Fluent API将WillCascadeDelete设置为至少其中一个路径的False.

我的问题是如何将Account.IdentityId和Policy.InsuredIdentityId属性配置为外键?我避免将任何导航/外键字段添加到标识类中,因为永远不应该有理由从标识导航到另一个类.这就是为什么我很难搞清楚这一点的原因?

public class Account
{
    public long Id { get; set; }
    public long IdentityId { get; set; }
    public virtual Identity Identity { get; set; }

    public ICollection<Policy> Policies { get; set; }
}

public class Policy
{
    public long Id { get; set; }

    public long AccountId { get; set; }
    public virtual Account Account { get; set; }

    public bool UseAccountIdentity { get; set; }
    public long InsuredIdentityId { get; set; }
    public virtual Identity InsuredIdentity { get; set; }
}

 public class Identity 
{        
    public long Id { get; set; }

    public string Name { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

public class AccountConfiguration : EntityTypeConfiguration<Account>
{
    public AccountConfiguration()
    {
        HasRequired(a => a.Identity).WithOptional(x => x.Account).WillCascadeOnDelete(false);
        HasMany(a => a.Policies).WithRequired(p => p.Account).HasForeignKey(p => p.AccountId);
    }
}

public class PolicyConfiguration : EntityTypeConfiguration<Policy>
{
    public PolicyConfiguration()
    {
        HasOptional(p => p.InsuredIdentity).WithOptionalPrincipal().WillCascadeOnDelete(false);
    }
}
Run Code Online (Sandbox Code Playgroud)

作为一个附带问题,EF Code First是否有任何好书或其他参考资料?我有Julia Lerman的编程实体框架:Code First,它适用于它覆盖的示例,但它没有涵盖足够的案例.

dan*_*wig 5

首先,public ICollection<Policy> Policies { get; set; }应该是public virtual ICollection<Policy> Policies { get; set; }.

只有当关系的一侧是一个,而另一侧是多个时,您才能映射EF外键属性.只要您具有1:1或1:0..1关系,依赖实体将使用与主体相同的主键.在这些情况下,不能有外键,因为从属的外键是其主键.

所以对此:

HasRequired(a => a.Identity).WithOptional(x => x.Account)
Run Code Online (Sandbox Code Playgroud)

...帐户的ID与身份的ID相同.这意味着,您可以IdentityIdAccount实体中完全删除该属性.但是我不明白该代码是如何编译的,因为Identity没有Account导航属性..?

当涉及到您的策略映射时,这真的是您想要的吗?您说策略可以与身份建立可选关系,但您的方式如下:

HasOptional(p => p.InsuredIdentity).WithOptionalPrincipal()
Run Code Online (Sandbox Code Playgroud)

...意味着一个人Identity只能(直接)做一个Policy.使映射看起来像这样有什么问题?

HasOptional(p => p.InsuredIdentity).WithMany()
    .HasForeignKey(x => x.InsuredIdentityId)
    .WillCascadeOnDelete(false);
Run Code Online (Sandbox Code Playgroud)

通过上述,您仍然没有从任何导航属性IdentityPolicy.你不需要一个,你只需要.WithMany()作为一个无法调用.但是,这会告诉数据库设置Identity为主体,并且Policy作为依赖项,因此您在db中具有正常的fk关系,并且仍然无法PolicyIdentityin代码导航到a .

其他的建议:

该策略还与Identity有关系,但它是可选的.

这意味着Policy.InsuredIdentityId应该是一个System.Nullable<long>.