EF один ко многим на части составного первичного ключа - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть три слоя таблиц в существующей базе данных, и я пытаюсь включить записи нижнего уровня, когда получаю данные среднего уровня ... Это должно быть отношение один ко многим - для отгрузки x с продуктом y тамявляются результатами анализа z.

public class Shipment
{
   [Key]
   public int Id { get; set; } 
   public string ShipName { get; set; }
   public DateTime ShipmentDate { get; set; }
}

public class ShipmentDetails
{
   [ForeignKey ("ShipmentId")]
   public int Id { get; set; } 
   [ForeignKey ("ProductId")]
   public int ProductId { get; set; }
   Public double Weight { get; set; }
   public virtual ShippingAnalysis Analysis { get; set; }
}

public class ShipmentAnalysis
{
   [ForeignKey ("ShipmentId")]
   public int Id { get; set; } 
   [ForeignKey ("ProductId")]
   public int TenantId { get; set; }
   [ForeignKey ("MetricId")]
   public int MetricId { get; set; }
   Public double Result { get; set; }
}

Я использую свободный способ определения составных первичных ключей.

modelBuilder.Entity<ShippingDetail>()
            .HasKey(c => new { c.ShipmentId, c.ProductlId });

modelBuilder.Entity<ShippingAnalysis>()
            .HasKey(c => new { c.ShipmentId, c.ProductId, c.MetricId });

Я получаю информацию о доставке с (один ко многим)Анализ записей.

var results = _context.ShippingDetail.Include(sd => sd.Analysis)
                                     .Where(sd => sd.ShipmentId == id);

Это не возвращает результат в почтальоне, но через браузер возвращает искаженный JSON.Если я откажусь от включения, он будет работать нормально.

1 Ответ

0 голосов
/ 27 ноября 2018

Проблема не в составном ключе, а в свойстве навигации (отсюда и определение взаимосвязи).Свойство навигации на (одной) стороне (если имеется) должно быть коллекция , а свойство навигации на (многих) стороне должно быть ссылка - см. Отношения - Определение терминов .

Согласно

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.

...