我的建议是更多地使用entity framework code first conventions。仅在您确实需要时才偏离它们(并且可以让您的项目负责人相信,这些偏离使您的类更易于理解、更好地测试、更好地维护等)
保持您的实体类简单 POCO,不要添加字段。让实体框架决定“集合”项应该是什么类型。
所以显然每个Defect 有零个或多个Images,每个Asset 也有零个或多个Images,每个Image 恰好属于一个Defect 和一个Assert,即@ 987654329@ 和 Asset 以及 Image 具有的外键。
如果您创建简单的一对多关系,那么就不会有任何问题。
Defect Id 1
Asset Id 3
// Traditional one-to-many: allows several images with same [Defect, Assert]
Image Id 10 with DefectId 1 and AssetId 3
Image Id 11 with DefectId 1 and AssetId 3
Image Id 12 with DefectId 1 and AssetId 3
问题出现了,因为你想使用这些外键作为主键。这可能是为了防止两个图像具有相同的 [Defect, Assert]。
// your composite key allows only one image with this [Defect, Assert]
Image Id [1, 3] with DefectId 1 and AssetId 3
// no other Image for this Defect 1 and Asset 3 possible
当且仅当您的模型表示不可能有多个具有相同 [缺陷,资产] 的图像的现实时,只有这样您的解决方案才会更好。
class Defect
{
public int Id {set; set;}
... // other properties
// every Defect has zero or more Images
public virtual ICollection<Image> Images {get; set;}
}
class Asset
{
public int Id {set; set;}
... // other properties
// every Asset has zero or more Images
public virtual ICollection<Image> Images {get; set;}
}
class Image
{
// composite primary key: [DefectId, AssetId]
// every Image belongs to exactly one Defect, using foreign key
public int DefectId {get; set;}
public virtual Defect Defect {get; set;}
// every Image belongs to exactly one Asset, using foreign key
public int AssetId {get; set;}
public virtual Asset Asset {get; set;}
}
在实体框架中,表的列由非虚拟属性表示,虚拟属性表示表之间的关系(一对多、多对多、...)
在你的情况下:不要忘记你的外键。
在 OnModelCreating 中:
var imageEntity = modelBuilder.Entity<Image>();
// every image has composite primary key
imageEntity.HasKey(image => new {image.DefectId, image.AssetId});
这(连同您的虚拟属性)可能足以让实体框架检测您的关系,尤其是主键和外键。如果没有,请告知实体框架:
// every image belongs to exactly one Defect, using foreign key
imageEntity.HasRequired(image => image.Defect)
.WithMany(defect => defect.Images)
.HasForeignKey(image => image.DefectId,
imageEntity.HasRequired(image => image.Asset)
.WithMany(asset => assert.Images)
.HasForeignKey(image => image.AssetId);