2013-09-25 2 views
1

У меня есть DbContext подклассМожно ли сложные типы ленивые нагрузки от службы WCF Data

ReportingContext : DbContext 

Как я делаю простой CRUD Затем я создал службу WCF Data, чтобы выставить свою DbSet ...

public class ReportService : DataService<ReportingContext> 

Я смог использовать ReportingContext напрямую, чтобы сделать «разбиение таблицы». В основном используют 2 объекта (ReportLayout и ReportLayoutData), которые используют одну таблицу. Я смог настроить это, используя свободный API. Все работало нормально в модульных тестах, поскольку я смог вернуть ReportLayouts и загружать только ReportLayoutData, когда они были доступны.

Мои проблемы возникли, когда я попытался сделать это через службу данных WCF, OData версии 5.6 - с использованием класса DataServiceContext. Возврат ReportLayouts работает нормально, но попытка ленивой загрузки зависимых данных пока не удавалось. Я пробовал разные вещи:

  • Вызов Включить через метод обслуживания на самом деле работал, когда я отлажена служба непосредственно и проверила сгенерированный SQL - 2 отдельных запросы, как для модульного тестирования. Однако служба просто не включала свойство ReportLayoutData в возвращаемые свойства при просмотре в браузере, и я получил ошибки на стороне клиента, связанные с отсутствующим свойством.

    [WebGet] 
    public IQueryable<ReportLayout> GetReportsByID(string ids) 
    { 
        var ints = GetInts(ids); 
        return CurrentDataSource.Reports.Include("LayoutData").Where(x => ints.Contains(x.ReportLayoutID)).AsQueryable(); 
    } 
    
    private static int[] GetInts(string ids) 
    { 
        return ids.Split(",".ToCharArray()).Select(x => Convert.ToInt32(x)).ToArray(); 
    } 
    
  • Я пытался использовать DataServiceContext.Expand - $ расширения - и это не удалось с различными ошибками, как я пытался slighly различных аргументов

  • Я пыталась дозвониться Execute, различные проблемы

  • я превратил свойство ReportLayoutData в IQueryable, хотя это отношение 1-1, и теперь он говорит, что ReportLayoutData не является свойством ReportLayout при запуске специального тестового модуля EF, который ранее работал нормально.

Мой вопрос: можно ли Ленивый нагрузки с помощью службы WCF Data в этом порядке, или я должен просто выставить 2 коллекции и решить результаты в единый объект на клиенте? Если это возможно, я просто хотел бы увидеть базовый шаблон - пару связанных объектов, текущие декларации API и код DataService. Спасибо за любую помощь.

EDIT

Я в настоящее время страдает от ошибок:

Свойство с именем «LayoutData» от типа «ReportLayout» имеет вид «Structural», но это, как ожидается, будет вида «Навигация».

Хотя нет никаких проблем извлечения данных в браузере: ReportService.svc/Reports() $ = расширение LayoutData

частичной трассировки стека:

Microsoft.Data.OData.ReaderValidationUtils.ValidateNavigationPropertyDefined (String PropertyName, IEdmEntityType owningEntityType, ODataMessageReaderSettings messageReaderSettings) на Microsoft.Data.OData.Atom.ODataAtomEntryAndFeedDeserializer.TryReadNavigationLinkInEntry (IODataAtomReaderEntryState entryState, Строка linkRelation, Строка linkHRef)

я смог удалить вышеуказанную ошибку, не подвергая 2 dbSets через службу. Будет рассматривать сервисную операцию, чтобы вернуть то, что мне нужно от EF, стыдно, что это не так элегантно.

+1

Во-первых, нет никакого способа с полки для реализации ленивой загрузки. Это, конечно, возможно. Однако я бы очень советовал ему. Круглое путешествие с OData обычно составляет порядка нескольких сотен мс. Ленивая загрузка по своей природе является синхронным рисунком. В типичном приложении пользователь будет отмечать невосприимчивость в несколько сотен мс. Если мы замкнуты, забудьте UX полностью. Вы можете взглянуть на «DataServiceContext.LoadProperty», но я бы посоветовал вам использовать асинхронные вызовы, когда это возможно. – Aron

+0

@Aron Спасибо за это - я попробовал LoadProperty, и если я правильно помню, он дал мне сообщение об ошибке, говорящее, что он работает только для коллекций. В то время мой ReportLayout выставлял только один * виртуальный объект ReportLayoutData *. Я мог бы попробовать это снова, хотя бы для удовлетворения увиденного. Я думаю, что вы правы в UX, но не видите проблемы, так как это будет только один запрос, и этот вызов можно сделать асинхронным. –

+0

@Aron Какая боль, если я сделаю свою ReportLayout.LayoutData коллекцию, я получаю исключение исключающего свойства при попытке создать экземпляр службы. Если я попытаюсь использовать LoadProperty с ReportLayout, имея только одно свойство объекта, которое я получаю - Закрытый тип Framework.Reports.ReportLayout не имеет соответствующего свойства ReportLayout/LayoutData. Раньше у меня была эта ошибка и думаю, что настало время для кофе и забыть о ленивой загрузке через WCF. –

ответ

0

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

Я был в состоянии реализовать такие запросы, как Отчеты/ReportService.svc/Отчеты (1) $ расширяющие = LayoutData в результате (AddQueryOption («$ расширение», «LayoutData») и написал метод сервиса, чтобы сделать это для кратных

[WebGet] 
    public IQueryable<ReportLayout> GetReportsByID(string ids) 

Я только разоблачил один Dbset через службу. - дети не являются доступный непосредственно.

стороне клиента обновления зависимых объектов может быть достигнуто с помощью методов DataServiceContext:

AddObject, AddLink 
AttachTo, UpdateObject, AttachLink //UpdateObject on the child ensures the entity state changes to modified (see DataServiceContext.Entites collection). 

Оглядываясь назад, я, наверное, не нужно разбить таблицу, но не имеют времени, чтобы играть с этим.

Смежные вопросы