Как я могу загрузить отношения сущностей второй степени с помощью службы данных WCF?

Я пытаюсь запросить отдельный объект в базе данных с помощью DataServiceQuery. Сущность, которую я пытаюсь загрузить, связана с графом других сущностей, которые я также хочу загрузить. MSDN описывает здесь и здесь, что я могу загрузить указанные объекты с помощью DataServiceQuery ‹TElement› .Expand или DataServiceContext.LoadProperty.

Это отлично работает для отношений первой степени моей сущности, но у меня проблема с загрузкой отношений отношений.

Очевидно, я мог вызвать LoadProperty для всех отношений второй степени и перебрать все коллекции второй степени, но я надеялся, что смогу загрузить весь граф отношений в одном запросе. Это возможно?

Изменить

На самом деле загрузка отношений второй степени не так очевидна. Следующий код не работает (модель предметной области изменена для ясности):

            var context = DataServiceReference.DataServiceContextFactory.Create();
            var customer = (from c in context.Customers.Expand("Orders")
                                where c.CustomerId.Equals(customerId)
                                 select c).First();
            foreach (var order in customer.Orders)
            {
                context.LoadProperty(order, "Products");

Последняя строка выше вызывает InvalidOperationException: «Контекст в настоящее время не отслеживает объект». Я использую самонастраивающиеся сущности. Может ли эта ошибка быть связана с STE?

Как бы я хоть как-то загрузил отношения второй степени?

Решение изменить

Оказывается, DataServiceQuery ‹TElement› .Expand использует другой синтаксис пути по сравнению с ObjectQuery ‹T› .Include. В первом случае в качестве разделителя пути используется косая черта, во втором - точка. Может ли кто-нибудь объяснить, почему синтаксис непоследователен и где я могу найти документацию по синтаксису пути Expand?


person Holstebroe    schedule 12.10.2010    source источник


Ответы (1)


DataServiceContextFactory - это ваш собственный класс, верно? (поскольку это не то, как вы обычно создаете экземпляр DataServiceContext). Предполагая, что в итоге создается обычный экземпляр DataServiceContext, тогда способ нетерпеливой загрузки нескольких уровней - это просто указать несколько уровней в вызове Expand. Так, например, context.Customers.Expand ("Orders / Products") вернет вам всех клиентов, их заказы и все продукты для этих заказов. Чтобы LoadProperty работала, убедитесь, что в вашем DataServiceContext для свойства MergeOption установлено значение одной из опций, позволяющих отслеживать. Обратите внимание, что отслеживание на стороне клиента не имеет ничего общего с отслеживанием EF на стороне сервера (технически это отдельный код на отдельной машине). Вы можете убедиться, что контекст отслеживает рассматриваемую сущность, пытаясь вызвать context.GetEntityDescriptor (myEntityInstance) Если он возвращает ненулевое значение, контекст отслеживает сущность, и LoadProperty должен работать.

person Vitek Karas MSFT    schedule 13.10.2010
comment
Да, фабрика контекста - это всего лишь простой фабричный класс, который создает контекст с использованием правильного URL-адреса. Моя проблема заключалась в том, что расширенный путь использует / Я привык включать, какие виды использования. в пути. Каково объяснение этой непоследовательной записи путей? - person Holstebroe; 13.10.2010
comment
Я попытался добавить строку context.MergeOption = MergeOption.OverwriteChanges; после создания контекста и перед загрузкой сущностей, но LoadProperty по-прежнему не работает, а context.GetEntityDescriptor (myEntityInstance) возвращает значение null. Как правильно включить отслеживание? - person Holstebroe; 13.10.2010
comment
Синтаксис Expand унаследован от синтаксиса URL-адреса $ expand. В URL-адресе / используется для разделения навигации, потому что это естественный способ навигации по URL-адресам. - person Vitek Karas MSFT; 13.10.2010
comment
Для отслеживания требуется, чтобы класс, который материализуется, был распознан как сущность. Итак, ваш класс Customer должен соответствовать правилам, чтобы его можно было распознать как сущность. Ему либо требуется свойство с именем ID, либо CustomerID, либо атрибут DataServiceKey, определяющий свойства ключа. Так ли это? - person Vitek Karas MSFT; 13.10.2010