我有一个Job
实体,它有两个相同类型的集合
public virtual ICollection<Device> ExistingDevices { get; set; }
public virtual ICollection<Device> NewDevices { get; set; }
在设备实体上,它返回Job
public int JobId { get; set; }
public virtual Job Job { get; set; }
从表面上看,这种方法很好,但是在数据库中,如果你看一个你看到的设备
//Devices Table in Db
|JobId | Job_Id | Job_Id1 |
我的设置包括使用流畅API的实体配置对象,但我还没有弄清楚如何解决这个问题。第一个JobId很好,它是对数据的完美描述。后两个引用它们所属的ExistingDevices
和NewDevices
列表。标题完全没有描述性。
是否可以将这些列重命名为更合适的列?
//修改
它具有FK JobId
,但如果设备位于ExistingDevices列表中,则JobId也会被放入Job_Id
并且Job_Id1
为空。如果设备属于NewDevices列表,则Job_Id
为空,Job_Id1
中包含JobId。
将Job_id命名为ExistingDevices,将Job_Id1命名为NewDevices将使Db更加清晰。
更新
睡了之后,我觉得这是一个设计错误。
我将Device
模型更改为
public bool NewDevice { get; set; }
并通过删除2个现有ICollections并添加
来更改Job
模型
public virtual ICollection<Device> Devices { get; set; }
我现在拥有一个具有正确描述性FK的设备集合,而不是拥有两个设备集合。在数据库中,1或0将指示新设备或现有设备。
答案 0 :(得分:1)
您有两对多关系,数据库将在从属实体(Device
)上有两个外键列。 JobId
可能代表ExistingDevices
而JobId1
代表NewDevices
。
要明确的是,您应该定义两个导航属性,如下所示。
public int? ExistingJobId { get; set; }
public virtual Job ExistingJob { get; set; }
public int? NewJobId { get; set; }
public virtual Job NewJob { get; set; }
然后可以使用Fluent Api配置关系。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Device>()
.HasOptional(x => x.ExistingJob)
.WithMany(x => x.ExistingDevices)
.HasForeignKey(x => x.ExistingJobId);
.WillCascadeOnDelete(true);
modelBuilder.Entity<Device>()
.HasOptional(x => x.NewJob)
.WithMany(x => x.NewDevices)
.HasForeignKey(x => x.NewJobId)
.WillCascadeOnDelete(false);
}
注意,在没有级联删除(false
)的情况下定义了一个外键,因为不允许multiple cascading delete。
更新:所需的现有作业和新作业已更改为可选。