我有以下代码。我想建立一个流畅的映射,以便我的Image具有一个由Defect_Id和Asset_Id组成的不可为空的复合主键。我该如何实现?我收到错误,属性“ Defect”不能用作实体“ TSIR.Core.Domain.Image”上的键属性,因为该属性类型不是有效的键类型。仅支持标量类型,字符串和字节[]。
public class Image
{
public Defect Defect { get; set; }
public int AssetId { get; set; }
}
public class Defect
{
public int Id { get; set; }
private ICollection<Image> _images;
public ICollection<Image> Images
{
get => _images ?? (_images = new Collection<Image>());
set => _images = value;
}
}
public ImageConfiguration()
{
ToTable("Images").HasKey(entity => new
{
Defect = entity.Defect,
entity.AssetId
});
}
答案 0 :(得分:1)
我的建议是更多地坚持使用entity framework code first conventions。仅在确实需要时才偏离它们(并可以使您的项目负责人确信,这些偏离使您的课程更易于理解,可测试性更好,可维护性更强,等等)
使您的实体类保持简单的POCO,不要添加字段。让实体框架决定“设置”项目应为哪种类型。
因此,显然每个Defect
都有零个或多个Images
,每个Asset
也有零个或多个Images
,每个Image
恰好属于一个{{ 1}}和一个Defect
,分别是Assert
具有外键的Defect
和Asset
。
如果您创建了简单的一对多关系,那么就不会有任何问题。
Image
出现问题,因为您要将这些外键用作主键。这可能是为了防止两个图像具有相同的[Defect,Assert]。
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
并且仅当您的模型代表一个现实,即不可能有多个具有相同[缺陷,资产]的图像时,这样您的解决方案才会更好。
// 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
在实体框架中,表的列由非虚拟属性表示,虚拟属性表示表之间的关系(一对多,多对多,...)
以您为例:不要忘记您的外键。
在OnModelCreating中:
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;}
}
对于实体框架来说,这(连同您的虚拟属性)可能足以检测您的关系,尤其是主键和外键。如果不是,请告知实体框架:
var imageEntity = modelBuilder.Entity<Image>();
// every image has composite primary key
imageEntity.HasKey(image => new {image.DefectId, image.AssetId});
答案 1 :(得分:0)
基本上,您不能将Defect对象包含在Key中。
在Image类上同时包含AssetId和DefectId的int属性。然后在配置中使用这些对象而不是导致错误的Defect对象。
window.addEventListener('popstate', () => window.location.reload())