#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
, если вас это интересует.