繁体   English   中英

正确配置不同属性的 EF Core 一对多映射

[英]Configuring EF Core one to many mapping of different properties correctly

I'm using AutoMapper to map classes from Camille to my own domain classes, which I plan on storing using EF Core in my .NET 5 REST API. 一个特别讨厌的 class 给我带来了很多麻烦。 ParticipantTimeline class 包含几个带有统计信息的字典,如下所示:

namespace MingweiSamuel.Camille.MatchV4
{
  public class ParticipantTimeline
  {
    [JsonPropertyName("participantId")]
    public int ParticipantId { get; set; }

    [JsonPropertyName("csDiffPerMinDeltas")]
    public IDictionary<string, double> CsDiffPerMinDeltas { get; set; }

    [JsonPropertyName("damageTakenPerMinDeltas")]
    public IDictionary<string, double> DamageTakenPerMinDeltas { get; set; }

    [JsonPropertyName("role")]
    public string Role { get; set; }

    [JsonPropertyName("damageTakenDiffPerMinDeltas")]
    public IDictionary<string, double> DamageTakenDiffPerMinDeltas { get; set; }

    [JsonPropertyName("xpPerMinDeltas")]
    public IDictionary<string, double> XpPerMinDeltas { get; set; }

    [JsonPropertyName("xpDiffPerMinDeltas")]
    public IDictionary<string, double> XpDiffPerMinDeltas { get; set; }

    [JsonPropertyName("lane")]
    public string Lane { get; set; }

    [JsonPropertyName("creepsPerMinDeltas")]
    public IDictionary<string, double> CreepsPerMinDeltas { get; set; }

    [JsonPropertyName("goldPerMinDeltas")]
    public IDictionary<string, double> GoldPerMinDeltas { get; set; }

    [JsonExtensionData]
    public Dictionary<string, object> _AdditionalProperties { get; set; } = new Dictionary<string, object>();

    //Methods omitted for brevity
  }

到目前为止,我正在映射到我的域类,如下所示:

CamilleProfile.cs:

// Omitted for brevity
CreateMap<ParticipantTimeline, ParticipantTimelineDto>();
CreateMap<KeyValuePair<string, double>, ParticipantTimelineDelta>()
    .ForMember(x => x.Delta, conf => conf.MapFrom(kvp => kvp.Key))
    .ForMember(x => x.Value, conf => conf.MapFrom(kvp => kvp.Value));

参与者时间线Dto.cs:

public class ParticipantTimelineDto
{
    public int ParticipantId { get; set; }
        
    public IEnumerable<ParticipantTimelineDelta> CsDiffPerMinDeltas { get; set; }
        
    public IEnumerable<ParticipantTimelineDelta> DamageTakenPerMinDeltas { get; set; }
        
    public string Role { get; set; }
        
    public IEnumerable<ParticipantTimelineDelta> DamageTakenDiffPerMinDeltas { get; set; }
        
    public IEnumerable<ParticipantTimelineDelta> XpPerMinDeltas { get; set; }
        
    public IEnumerable<ParticipantTimelineDelta> XpDiffPerMinDeltas { get; set; }
        
    public string Lane { get; set; }
        
    public IEnumerable<ParticipantTimelineDelta> CreepsPerMinDeltas { get; set; }
   
    public IEnumerable<ParticipantTimelineDelta> GoldPerMinDeltas { get; set; }
}

参与者时间线Delta.cs:

public class ParticipantTimelineDelta
{
    public string Delta { get; set; }
    public double Value { get; set; }

    public ParticipantTimelineDelta()
    {
    }
}

这在没有 EF 的情况下工作正常,但现在我正在尝试为身份添加迁移,但我无法弄清楚我与 EF 的映射。 尝试创建迁移时,我收到以下消息:

在没有配置外键属性的情况下,“ParticipantTimelineDelta”和“ParticipantTimelineDto”之间存在多种关系。 这将导致实体框架在“ParticipantTimelineDelta”上创建影子属性,其名称取决于发现顺序。

这只是一个警告,我理解它为什么这么说。 这是让我最困惑的实际错误。 如下:

实体类型“ParticipantTimelineDelta”需要定义一个主键。 如果您打算使用无密钥实体类型,请在“OnModelCreating”中调用“HasNoKey”。 有关无密钥实体类型的详细信息,请参阅https://go.microsoft.com/fwlink/?linkid=2141943。

这让我很困惑,因为我确实定义了一个 PK。 我不是特别喜欢我映射增量的方式,但是我还没有找到更好的方法来 devise。 无论如何,我想知道以我当前的配置是否有可能完全正确地对它们进行 map。 如果没有,我应该如何 map 否则三角洲?

这是我对 ParticipantTimeline 和 ParticipantTimelineDelta 的 EF 配置:

参与者时间线配置.cs:

public class ParticipantTimelineConfiguration : IEntityTypeConfiguration<ParticipantTimelineDto>
{
    public void Configure(EntityTypeBuilder<ParticipantTimelineDto> builder)
    {
        builder.ToTable("ParticipantTimeline");
        builder.HasKey(ps => ps.ParticipantId);
        builder.HasMany<ParticipantTimelineDelta>()
            .WithOne();
    }
}

参与者时间线DeltaConfiguration.cs:

public class ParticipantTimelineDeltaConfiguration : IEntityTypeConfiguration<ParticipantTimelineDelta>
{
    public void Configure(EntityTypeBuilder<ParticipantTimelineDelta> builder)
    {
        builder.ToTable("ParticipantTimelineDeltas");
        builder.HasKey(d => d.Delta);
    }
}

我尝试在 HasMany().WithOne() 语句上定义 HasForeignKey,但无济于事。

Ivan Stoev 的评论最终为我指明了正确的方向。 我对 ParticipantTimelineConfiguration 进行了以下更改:

public class ParticipantTimelineConfiguration : IEntityTypeConfiguration<ParticipantTimelineDto>
{
    public void Configure(EntityTypeBuilder<ParticipantTimelineDto> builder)
    {
        builder.ToTable("ParticipantTimeline");
        builder.HasKey(ps => ps.ParticipantId);
        builder.OwnsMany(pt => pt.CreepsPerMinDeltas, a =>
        {
            a.WithOwner().HasForeignKey("ParticipantTimelineId");
            a.Property<int>("Id");
            a.HasKey("Id");
        });
        builder.OwnsMany(pt => pt.CsDiffPerMinDeltas, a =>
        {
            a.WithOwner().HasForeignKey("ParticipantTimelineId");
            a.Property<int>("Id");
            a.HasKey("Id");
        });
        builder.OwnsMany(pt => pt.DamageTakenDiffPerMinDeltas, a =>
        {
            a.WithOwner().HasForeignKey("ParticipantTimelineId");
            a.Property<int>("Id");
            a.HasKey("Id");
        });
        builder.OwnsMany(pt => pt.DamageTakenPerMinDeltas, a =>
        {
            a.WithOwner().HasForeignKey("ParticipantTimelineId");
            a.Property<int>("Id");
            a.HasKey("Id");
        });
        builder.OwnsMany(pt => pt.GoldPerMinDeltas, a =>
        {
            a.WithOwner().HasForeignKey("ParticipantTimelineId");
            a.Property<int>("Id");
            a.HasKey("Id");
        });
        builder.OwnsMany(pt => pt.XpDiffPerMinDeltas, a =>
        {
            a.WithOwner().HasForeignKey("ParticipantTimelineId");
            a.Property<int>("Id");
            a.HasKey("Id");
        });
        builder.OwnsMany(pt => pt.XpPerMinDeltas, a =>
        {
            a.WithOwner().HasForeignKey("ParticipantTimelineId");
            a.Property<int>("Id");
            a.HasKey("Id");
        });
    }
}

这不是特别漂亮的imo,我希望有更好的方法来做到这一点。 但是,这暂时可以。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM