Как обрабатываются реляционные элементы из LINQ в SQL DataContext при отправке объектов через WCF?

#c# #.net #wcf #linq-to-sql

#c# #.net #wcf #linq-to-sql

Вопрос:

Допустим, у меня есть реляционная база данных с таблицами: OrderableCategories и Orderables. Они находятся в отношении один ко многим с одной упорядочиваемой категорией, присоединенной к нескольким упорядочиваемым объектам. Следовательно, экземпляр OrderableCategory в LINQ имеет элементы: ID , Name и EntitySet<Orderable> Orderables . При отправке через WCF (wsHttpBinding, если это вообще имеет значение) набор объектов преобразуется в simple Orderable[] . Orderable Экземпляр также содержит элемент с именем OrderableCategory , который является просто экземпляром категории этого упорядочиваемого объекта. При отправке через WCF, я предполагаю, происходит что-то вроде этого: Orderable экземпляр заполняет свой OrderableCategory экземпляр полями из этой категории, но его Orderable[] также заполняются другими упорядочиваемыми объектами в этой категории. Эти упорядочиваемые объекты OrderableCategory снова заполняются этой категорией и так далее, так что я теоретически мог бы вызвать (для полученного упорядочиваемого o): o.OrderableCategory.Orderables[0].OrderableCategory.Orderables[0]. (...) и так далее. Я только предполагаю, что сервер попадает в бесконечный цикл, и когда размер сообщения превышает квоту, он отключается, и я вижу исключение завершения работы службы. Как я могу избежать этого сценария и воспользоваться преимуществами отношений в моей базе данных? Я думаю, что мои подозрения верны, потому что, когда я отключил одно из свойств (сделал его внутренним в LINQ Class Designer), данные заполняются только «односторонне» и у Orderable больше нет своего OrderableCategory элемента, это работает. Но я хотел бы знать, можно ли этого достичь без ущерба для свойства.

Ответ №1:

Это должно быть обработано путем пометки объектов DataContract атрибутом и присвоения его IsReference свойству значения true . Это даст указание DataContractSerializer отслеживать ссылки вместо сериализации объектов, как вы описали.

Linq-To-Sql designer / SQLMetal должен сделать это за вас, установив Serialization Mode значение Unidirectional .

Ответ №2:

Если вы отправляете объекты через WCF, такие приятные функции, как отложенная загрузка, конечно, исчезают.

В основном вам нужно решить, какой из двух вариантов вы хотели бы использовать:

  • если вы запрашиваете объект OrderableCategory , вы можете вернуть только его базовые «атомарные» свойства, например ID, Name и так далее. Преимущество заключается в меньшем размере — вы отправляете обратно меньше данных

  • или альтернативно: если вы запрашиваете объект OrderableCategory , вы можете вернуть его базовые свойства плюс вы могли бы загрузить целый список Orderables , который содержит эта категория, и вернуть оба одновременно; преимущество: у вас есть эти данные, доступные сразу, но с другой стороны, вам придется отправлять намного больше данных.

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