具有流畅映射的实体框架-复合主键,一对多

时间:2019-02-11 20:55:04

标签: entity-framework

我有以下代码。我想建立一个流畅的映射,以便我的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
    });
}

2 个答案:

答案 0 :(得分:1)

我的建议是更多地坚持使用entity framework code first conventions。仅在确实需要时才偏离它们(并可以使您的项目负责人确信,这些偏离使您的课程更易于理解,可测试性更好,可维护性更强,等等)

使您的实体类保持简单的POCO,不要添加字段。让实体框架决定“设置”项目应为哪种类型。

因此,显然每个Defect都有零个或多个Images,每个Asset也有零个或多个Images,每个Image恰好属于一个{{ 1}}和一个Defect,分别是Assert具有外键的DefectAsset

如果您创建了简单的一对多关系,那么就不会有任何问题。

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())