Вложенные свойства с наследованием - PullRequest
0 голосов
/ 08 мая 2019

У интернет-магазина, над которым я работаю, есть лицо Заказ , в котором есть участник DeliveryDetails .Цель DeliveryDetails состоит в том, чтобы содержать данные, которые являются специфическими для метода доставки, выбранного пользователем (например, Доставка или Получение из магазина), в то время как некоторые детали являются общими для всех методов (например, Имя, Фамилия, Номер телефона).Я думал о структуре, подобной следующей, используя наследование:

public class Order {
        // ....other props...
        public DeliveryMethodType DeliveryMethodType { get; set; }
        public DeliveryDetailsBase DeliveryDetails { get; set; }
}

    public class DeliveryDetailsBase
    {
        public int Id { get; set; }
        public string CustomerId { get; set; }
        public Order Order { get; set; }
        public int OrderId { get; set; }

        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public string PhoneNumber { get; set; }
    }

    public class DeliveryDetailsShipping : DeliveryDetailsBase
    {
        public string Street { get; set; }
        public string Building { get; set; }
        public string Appartment { get; set; }
        public string PostalCode { get; set; }
        public string City { get; set; }
        public string Country { get; set; }
    }

    public class DeliveryDetailsPickupFromStore : DeliveryDetailsBase
    {
        public string StoreCode { get; set; }
    }

Однако я не могу понять, как заставить DeliveryDetails реквизит быть назначенным различным типам деталей способа доставки в зависимостио том, какой метод выбрал клиент и как его использовать в EntityFramework на ASP.Core.

Обходные пути, которые я уже пробовал:

-> (1).Создание связующего реквизита «суперкласса» для ВСЕХ методов доставки и заполнение в БД только тех, которые необходимы для выбранного метода доставки (выбор с помощью установки enum DeliveryMethodType ). ИТОГ : работает, но с 1 большой и уродливой таблицей с несколькими нулями.

-> (2).В Заказ , создание реквизита DeliveryDetails , который в свою очередь включает DeliveryDetailsPickupFromStoreDATA & DeliveryDetailsShippingDATA . OUTCOME : работает, но с несколькими связанными таблицами и довольно уродливым кодом, проверяет выбранный тип из enum, создает конкретный подкласс для выбранного метода доставки и устанавливает в ноль другие неиспользуемые подклассы.

Подвести итоги: Есть ли более изящный и выполнимый способ организовать это?

Ответы [ 2 ]

0 голосов
/ 08 мая 2019

"Есть ли более изящный и выполнимый способ организовать это?"Держите это простым, и наследование обычно не просто.:)

Как правило, я выбираю композицию вместо наследования.С ним легче работать.При наличии заказа, который необходимо доставить по адресу или в магазин:

public class Order
{
  public DeliveryMethod DeliveryMethod { get; set; } = DeliveryMethod.None;

  public virtual OrderDeliveryAddress { get; set; } // should never be null.
  public virtual OrderDeliveryStore { get; set; } // not null if delivery mode = store.
}

public class Address
{
  public string Street { get; set; }
  public string Building { get; set; }
  public string Appartment { get; set; }
  public string PostalCode { get; set; }
  public string City { get; set; }
  public string Country { get; set; }   
}

public class OrderDeliveryAddress
{
  public virtual Order Order { get; set; }
  public virtual Address Address { get; set; }
}

public class Store
{
  public int StoreId { get; set; }
  public virtual Address { get; set; }
}

public class OrderDeliveryStore
{
  public virtual Order Order { get; set; }
  public virtual Store Store { get; set; }
}

, где DeliveryMethod - это Enum.{None = 0, ToAddress, ToStore}

Когда заказ размещен, оператор может решить доставить его по адресу, выбрать адрес клиента или ввести новую запись адреса;или они могут доставить его в магазин, который также может установить адрес OrderDeliveryAddress в адрес магазина.Вы можете установить проверки в базе данных / системе, чтобы гарантировать, что целостность данных для метода доставки и ссылки OrderDeliveryAddress / OrderDeliveryStore синхронизированы и выявляют любые несоответствия, которые могут появиться.

Одним из соображений может быть то, что когда дело доходит до поставок, вы, вероятно, захотите клонировать новую запись адреса, основанную на адресе клиента, или сохранить адрес в зависимости от обстоятельств во время заказа, а не ссылаться на их текущую запись адреса.по ID.Причина будет в исторической целостности.В этот момент заказ будет доставлен по адресу, и если в будущем адрес клиента или магазина изменится, в предыдущих заказах все равно должен быть указан адрес, по которому был доставлен заказ.

0 голосов
/ 08 мая 2019

В EF Core реализовано только Таблица на иерархию (TPH) наследование.

Таблица для каждого типа (TPT) все еще открытый билет (не реализовано).

Таблица для конкретного типа (TPC) также все еще открытый билет (не реализовано).

Итак, если TPH отвечает вашим требованиям, вы можете следовать этому руководству .По сути, будет использоваться одна таблица, а дополнительный столбец с именем Discriminator будет использоваться для определения, какой реализации соответствует запись.

Если вы только начинаете работу с Entity, я бы рекомендовал не использовать наследование.и просто используйте пустые столбцы для данных, которые могут или не могут быть необходимы в зависимости от типа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...