[英]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.