Проблема не в составном ключе, а в свойстве навигации (отсюда и определение взаимосвязи).Свойство навигации на (одной) стороне (если имеется) должно быть коллекция , а свойство навигации на (многих) стороне должно быть ссылка - см. Отношения - Определение терминов .
Согласно
modelBuilder.Entity<ShippingDetail>()
.HasKey(c => new { c.ShipmentId, c.ProductlId });
modelBuilder.Entity<ShippingAnalysis>()
.HasKey(c => new { c.ShipmentId, c.ProductId, c.MetricId });
отношение должно быть ShippingDetail
(один) -> (много) ShippingAnalysis
, следовательно,
public virtual ShippingAnalysis Analysis { get; set; }
свойство ShippingDetail
должно быть
public virtual ICollection<ShippingAnalysis> Analysis { get; set; }
Этого должно быть достаточно для EF Core, чтобы определить правильные составные столбцы FK.Но если вы хотите быть на сто процентов уверены (явное никогда не повредит), добавьте следующую свободную конфигурацию:
modelBuilder.Entity<ShippingDetail>()
.HasMany(e => e.Analysis)
.WithOne() // make sure to specify navigation property if exists, e.g. e => e.NavProp
.HasForeignKey(e => new { e.ShipmentId, e.ProductId });
PS Удалите все эти [ForeignKey]
аннотации данных.Они делают разные вещи в зависимости от того, применяются ли они к свойству FK или свойству навигации, и наверняка не делают то, что думают, и иногда могут фактически привести к неожиданному поведению.Исходя из моего опыта работы с отношениями EF Core, пусть соглашения EF Core справятся со своей задачей или используют свободный API.