Один-на-один родительский ребенок SQL Временная таблица КАК ВСЕ - PullRequest
0 голосов
/ 12 марта 2020

Настройка SQL Сервер 2016. Net 4.7.2 EF6

Документация MSDN и Мягкие обновления с временными таблицами оба очень полезны, но они делают нет примера, где есть связь между таблицами.

Давайте предположим, что у нас есть пример с Order и OrderItems. Как вы можете видеть, у сущности Order есть Компания, и между ними существует референтная связь. Order также имеет сложный тип как свойство (без идентификатора). Я создал таблицы базы данных, а столбцы sysStartTime и sysEndTime скрыты и заполнены сервером SQL.

Объекты добавляются в базу данных с помощью EF6 , Я также добавил настраиваемые конфигурации сопоставления через Fluent API (HasMany (...). WithRequired (..)

Все работает как положено. Объекты добавляются, ключи создаются как положено, SysStartTime точно такой же между таблицами Order и OrderItem.

Предположим, что я хочу запросить данные в SQL, используя функциональность AS OF ALL . Это означает, что я не могу использовать обычный DbContext. Заказывает IDbSet, потому что он не будет инициировать запрос к таблице истории. Прежде всего, для того, чтобы получить правильный набор родительско-дочерней версии, объединения двух таблиц с использованием функциональности внешнего ключа недостаточно. Мне нужно добавить SysStartTime в условии соединения, в противном случае я получу дубликаты. Один из сценариев, где это проявляется, - это если вы выполняете обновление в существующей сущности. У вас будет 2 строки в родительской таблице (одна в главной и одна в истории) и 2 * n строк в дочерней таблице (n в основной и n в истории).

постоянно означает, что временная таблица feauture не идеальна для такого рода отношений между таблицами?

Если я попытаюсь сделать то же самое в C#, у меня возникнут следующие проблемы: Переход по маршруту Заказы:

DbContext.Orders.SqlQuery("....only related to the orders table .. AS OF ALL").ToList()

Я получаю исключение, поскольку отображение типов примитивов поддерживается только с помощью метода SqlQuery.

Переход по маршруту базы данных:

DbContext.Database.SqlQuery<OrderDto>("
... dbo.Order AS OF ALL order
INNER JOIN dbo.OrderItem orderItem
  ON order.Id = orderItem.Id
  AND order.SysStartTime = orderItem.SysStartTime")

Я могу написать запрос, который содержит все данные, которые мне нужны (из обеих таблиц) и сопоставить их с пользовательским объектом dto. Все идет нормально. Проблема возникает, когда я пытаюсь преобразовать dto в реальную сущность и воссоздать граф объекта. Когда я проектировал объекты, все свойства были доступны только для чтения, и Id не был частью конструктора. Необходимость изменить это кажется неправильным.

Есть ли способ получить функциональность "КАК ВСЕ" для родительских и дочерних объектов со свойствами навигации, заполненными с помощью EF6? Я видел, что есть некоторые EF Core расширения , но изменение с. NET 4.7.2 не вариант.

    public class Company
    {
        public int Id { get; private set; }
        public string Name { get; private set; }
    }

    public class ComplexType
    {
        public string ComplexCode { get; private set; }
        public string ComplexName { get; private set; }
    }

    public class Order
    {
        public int Id { get; private set; }
        public Company Company { get; private set; }
        public ComplexType ComplexType { get; private set; }
        public string Name { get; private set; }
        public ICollection<OrderItem> OrderItems { get; private set; }
        public int CompanyId { get; private set; }

        private Order()
        {
            // EF only
        }

        public Order(Company company,
            ComplexType complexType,
            string name,
            ICollection<OrderItem> orderItems)
        {
            Company = company;
            ComplexType = complexType;
            Name = name;
            OrderItems = orderItems;
        }
    }

    public class OrderItem
    {
        public int Id { get; private set; }
        public Order Order {get; private set;}
        public decimal Price { get; private set; }
        public int OrderId { get; private set; }

        private OrderItem()
        {
            // EF only
        }
        public OrderItem(Order order, decimal price)
        {
            Order = order;
            Price = price;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...