Entity framework 如何首先在实体框架代码中使用fluent映射创建多个相同类型的非空属性
我使用EF5,采用代码优先和流畅的映射方法。以下是我的场景,为了清晰起见,将其删减:Entity framework 如何首先在实体框架代码中使用fluent映射创建多个相同类型的非空属性,entity-framework,ef-code-first,Entity Framework,Ef Code First,我使用EF5,采用代码优先和流畅的映射方法。以下是我的场景,为了清晰起见,将其删减: public class SecuritySettings { public int Id { set; set } public Company Company { get; set; } public int MaximumInvalidPasswordAttempts { get; set; // etc. } public class Company { public i
public class SecuritySettings
{
public int Id { set; set }
public Company Company { get; set; }
public int MaximumInvalidPasswordAttempts { get; set;
// etc.
}
public class Company
{
public int Id { set; set }
public string Name { get; set; }
public SecuritySettings InternalUserSecuritySettings { get; set; }
public SecuritySettings ExternalUserSecuritySettings { get; set; }
}
仅凭上述内容,我就可以在公司表中获得两个FK:
InternalUserSecuritySettings_Id int, null
ExternalUserSecuritySettings_Id int, null
到目前为止,一切顺利
我有一些配置类用来设置我的流畅映射——一个用于公司,一个用于安全设置。这些规定了所需的属性。在公司配置中,如果我执行以下操作:
HasRequired(x => x.InternalUserSecurityConfiguration);
这导致:
InternalUserSecuritySettings\u Id int,不为null
ExternalUserSecuritySettings\u Id int,null
但是,如果我再加上:
HasRequired(x => x.ExternalUserSecurityConfiguration);
我得到以下例外情况:
在表“companys”上引入外键约束“FK_dbo.companys_dbo.SecuritySettings\u ExternalUserSecurityConfiguration\u Id”可能会导致循环或多个级联路径。指定“在删除时不执行操作”或“在更新时不执行操作”,或修改其他外键约束
我试过:
我确实找到了一种方法,通过对实际外键使用单独的属性来实现这一点,但首先,对于非空要求,这似乎是额外的努力;其次,我必须使用“WithMany()”映射在OnModelCreating方法中声明许多配置,这对我来说是违反直觉的 您可以通过使用以下命令来使用非空属性:
modelBuilder.Entity<Company>().
HasRequired(x => x.InternalUserSecuritySettings)
.WithMany()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Company>().
HasRequired(x => x.ExternalUserSecuritySettings)
.WithMany()
.WillCascadeOnDelete(false);
它应该映射到SecuritySettings
实体的哪一端(内部还是外部?),因为无法通过上面的场景判断它是无效的
您可以将两个不同的
SecuritySettings
集合添加到您的公司,然后您就有了一个正确的映射。RE:Mark Oreta-当我查看源代码管理历史记录时,公司属性最初并不存在-它一定是我的“让我们尝试一下,看看会发生什么”尝试之一!我已经删除了它,因为我不需要在没有在公司上下文中引用安全设置的情况下引用安全设置。我确实有一个与您类似的版本,但我将您的作为答案,因为我能够从您的答案引导到至少能够在我的CompanyConfiguration类中添加所有映射,而不是在OnModelCreating方法中。现在唯一的痛处是,这些仍然意味着一对一的映射,而WithMany()不能推断或执行这些映射。所以,我唯一能强迫它通过的方法就是使用一个唯一的约束。不太漂亮!谢谢你的时间和回答
编辑:
只想分享我对这个问题的当前答案:
公共类公司配置:DataEntityBaseConfiguration
{
上市公司配置()
{
属性(x=>x.Name).IsRequired();
属性(x=>x.Name).HasMaxLength(256);
HasRequired(x=>x.InternalUserSecurityConfiguration)。WithMany().WillCascadeOnDelete(false);
HasRequired(x=>x.ExternalUserSecurityConfiguration)。WithMany().WillCascadeOnDelete(false);
}
}
然后,在我的上下文初始化器类中,我添加了以下代码行,以对两个属性强制执行唯一约束:
AddUniqueConstraint<Company>(() => new Company().ExternalUserSecurityConfigurationId);
AddUniqueConstraint<Company>(() => new Company().InternalUserSecurityConfigurationId);
AddUniqueConstraint(()=>new Company().ExternalUserSecurityConfiguration ID);
AddUniqueConstraint(()=>new Company().InternalUserSecurityConfiguration ID);
其中AddUniqueConstraint是我编写的一个方法,用于执行sql以创建一个唯一的contraint-请跟随阅读更多内容
public class CompanyConfiguration : DataEntityBaseConfiguration<Company>
{
public CompanyConfiguration()
{
Property(x => x.Name).IsRequired();
Property(x => x.Name).HasMaxLength(256);
HasRequired(x => x.InternalUserSecurityConfiguration).WithMany().WillCascadeOnDelete(false);
HasRequired(x => x.ExternalUserSecurityConfiguration).WithMany().WillCascadeOnDelete(false);
}
}
AddUniqueConstraint<Company>(() => new Company().ExternalUserSecurityConfigurationId);
AddUniqueConstraint<Company>(() => new Company().InternalUserSecurityConfigurationId);