Могу ли я преобразовать значение моего первичного ключа в определенное отношение c один ко многим, используя Fluent API? - PullRequest
1 голос
/ 25 января 2020

Я пытаюсь вручную убрать часть существующей схемы базы данных в EF Core 2.2. Рассматриваемая база данных является частью стороннего программного обеспечения ERP, и я не контролирую структуру самой базы данных, поэтому я пытаюсь работать с тем, что мне дают. Пока все идет хорошо, однако я столкнулся с проблемой из-за сомнительного выбора дизайна базы данных поставщиком ERP.

Рассмотрим следующие отношения один-ко-многим, которые я пытаюсь встроить в свой OnModelCreating () метод в моем DbContext (через Fluent API):

modelBuilder.Entity<SalesOrderHeader>(s => {
   s.HasMany<WorkOrderHeader>(e => e.WorkOrders)
      .WithOne()
      .HasPrincipalKey(e => e.SalesOrderNumber)
      .HasForeignKey(e => e.RelatedPO_SONumber);
});

Это почти то, что мне нужно, однако в таблице WorkOrders «RelatedPO_SONumber» имеет тип string, где «SalesOrderNumber» в таблице SalesOrderHeaders имеет тип внутр. Кроме того, то, что хранится в «RelatedPO_SONumber», представляет собой строку с 0 дополнениями (всегда длиной 8 символов) «SalesOrderNumber» (например, SalesOrderHeader.SalesOrderNumber = 1234567, WorkOrder.RelatedPO_SONumber = "01234567").

Вот что я попытался и может помочь проиллюстрировать то, что я пытаюсь сделать с помощью спецификатора формата (бросает ArgumentException "Выражение должно представлять простой доступ к свойству: 't => t.MyProperty'"):

modelBuilder.Entity<SalesOrderHeader>(s => {
   s.HasMany<WorkOrderHeader>(e => e.WorkOrders)
      .WithOne()
      .HasPrincipalKey(e => e.SalesOrderNumber.ToString("D8"))
      .HasForeignKey(e => e.RelatedPO_SONumber);
});

Я пытался альтернативный подход, заключающийся в создании другого свойства в моем определении сущности SalesOrderHeader и использовании его в качестве аргумента для HasPrincipalKey ():

// within SalesOrderHeader
[NotMapped]
public string ZeroPaddedSONumber => SalesOrderNumber.ToString("D8");

// within DbContext OnModelCreating()
modelBuilder.Entity<SalesOrderHeader>(s => {
   s.HasMany<WorkOrderHeader>(e => e.WorkOrders)
      .WithOne()
      .HasPrincipalKey(e => e.ZeroPaddedSONumber)
      .HasForeignKey(e => e.RelatedPO_SONumber);
});

Это привело к:

"InvalidOperationException : Не найдено поле поддержки для свойства 'ZeroPaddedSONumber' типа сущности 'SalesOrderHeader', и у свойства нет установщика. "

Есть ли способ передать что-либо, кроме строгой ссылки на свойство , а точнее преобразованная "версия" этого свойства? "

Спасибо заранее д.

РЕДАКТИРОВАТЬ: После предложения в комментарии я попробовал это:

modelBuilder.Entity<SalesOrderHeader>(s => {
   s.Property(e => e.SalesOrderNumber)
      .HasConversion(n => n.ToString("D8"), s => int.Parse(s));

   s.HasMany<WorkOrderHeader>(e => e.WorkOrders)
      .WithOne()
      .HasPrincipalKey(e => e.SalesOrderNumber)
      .HasForeignKey(e => e.RelatedPO_SONumber);
});

Это тоже не работает, я получаю следующее исключение (я получаю то же исключение если я пропущу преобразование):

Типы свойств, указанные для внешнего ключа {'RelatedPO_SONumber'} в типе сущности 'WorkOrderHeader', не соответствуют типам свойств в основном ключе { 'SalesOrderNumber'} для типа сущности 'SalesOrderHeader'.

...