Entity Framework - простая загрузка объектов, связанных с подклассом

Интересно, есть ли возможность получать объекты, связанные с загрузкой, для определенного подкласса данного класса.

Структура класса ниже

Заказ имеет отношение ко многим базовым классам подпорядков (SuborderBase). Класс MySubOrder наследуется от SuborderBase. Я хочу указать путь для Include() для загрузки объектов, связанных с MySubOrder (Customer) при загрузке заказа, но у меня возникла ошибка, заявляющая, что между SuborderBase и Customer нет никакой связи. Но существует связь между MySubOrder и клиентом.

Ниже приведен запрос, который не работает

Context.Orders.Include("SubOrderBases").Include("SubOrderBases.Customers")

Как я могу явно указать это?

Update. Схема сущности ниже enter image description here

Ответ 1

Это решение, которое требует только одного обратного перехода:

var orders = Context.Orders
    .Select(o => new
    {
        Order = o,
        SubOrderBases = o.SubOrderBases.Where(s => !(s is MyOrder)),
        MyOrdersWithCustomers = o.SubOrderBases.OfType<MyOrder>()
            .Select(m => new
            {
                MyOrder = m,
                Customers = m.Customers
            })
    })
    .ToList()  // <- query is executed here, the rest happens in memory
    .Select(a => 
    {
        a.Order.SubOrderBases = new List<SubOrderBase>(
            a.SubOrderBases.Concat(
            a.MyOrdersWithCustomers.Select(m => 
                {
                    m.MyOrder.Customers = m.Customers;
                    return m.MyOrder;
                })));
        return a.Order;
    })
    .ToList();

Это в основном проекция в коллекцию анонимного типа. После этого результат запроса преобразуется в объекты и свойства навигации в памяти. (Он также работает с отключенным отслеживанием.)

Если вам не нужны сущности, вы можете пропустить всю часть после первого ToList() и работать непосредственно с результатом анонимных объектов.

Если вы должны изменить этот граф объекта и потребовать отслеживания изменений, я не уверен, что этот подход безопасен, поскольку свойства навигации не полностью установлены при загрузке данных - например, MyOrder.Customers - null после проецирования а затем установление свойств отношений в памяти может быть обнаружено как модификация, которой она не является, и вызвать проблемы при вызове SaveChanges.

Прогнозы выполняются для сценариев только для чтения, а не для модификаций. Если вам требуется отслеживание изменений, вероятно, более безопасный способ состоит в том, чтобы загружать полные объекты в несколько обращений, так как нет возможности использовать Include в одном обратном переходе для загрузки всего графика объекта в вашей ситуации.

Ответ 2

Предположим, что u загрузил список заказов как lstOrders, попробуйте следующее:

foreach (Orders order in lstOrders)
    order.SubOrderBases.Load();

и то же самое для клиентов.