簡體   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