![](/img/trans.png)
[英]EF Code First 5 - How to define nullable foreign key using Fluent API?
[英]EF6 Code First: Using Fluent API to declare a Foreign Key
我正在与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);
}
}
作为一个附带问题,EF Code First是否有任何好书或其他参考资料? 我有Julia Lerman的编程实体框架:Code First,它适用于它所覆盖的示例,但它没有涵盖足够的案例。
首先, public ICollection<Policy> Policies { get; set; }
public ICollection<Policy> Policies { get; set; }
public ICollection<Policy> Policies { get; set; }
应该是public virtual ICollection<Policy> Policies { get; set; }
public virtual 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)
...帐户的ID与身份的ID相同。 这意味着,您可以从Account
实体中完全删除IdentityId
属性。 但是我不明白该代码是如何编译的,因为Identity
没有Account
导航属性..?
当涉及到您的策略映射时,这真的是您想要的吗? 您说策略可以与身份建立可选关系,但您的方式如下:
HasOptional(p => p.InsuredIdentity).WithOptionalPrincipal()
...表示Identity
只能与(直接)做一个Policy
。 使映射看起来像这样有什么问题?
HasOptional(p => p.InsuredIdentity).WithMany()
.HasForeignKey(x => x.InsuredIdentityId)
.WillCascadeOnDelete(false);
有了上述内容,您仍然没有从Identity
到Policy
任何导航属性。 你不需要一个,你只需要调用.WithMany()
作为无法参与。 但是,这告诉数据库将Identity
设置为主体,将Policy
为依赖,因此您在db中具有正常的fk关系,并且仍然无法从代码中的Identity
导航到Policy
。
其他的建议:
该策略还与Identity有关系,但它是可选的。
这意味着Policy.InsuredIdentityId
应该是System.Nullable<long>
。
我的问题是概念性的。 虽然通常身份只适用于一个帐户(导致我将其可视化为1:1),但理论上,身份可以使用一次以上,因此可以使用多个帐户。 如果我使用以下配置,我会得到我想要的。 然后由我来执行任何规则,例如身份只能用于一个帐户(但需要尽可能多的策略)
public class IdentityConfiguration : EntityTypeConfiguration<Identity>
{
public IdentityConfiguration()
{
HasMany(i => i.Accounts).WithRequired(i => i.Identity).HasForeignKey(a => a.IdentityId);
}
}
或者,我可以将Identity作为主实体,将Account作为可选的依赖。 这可行,因为所有帐户都有一个身份,但并非所有身份都与帐户相关联。 帐户将不再拥有自己的密钥。
这不直观,这有点令人担忧。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.