Как управлять отношениями в таблицах Azure, которые являются свойствами списка в коде

У меня вопрос о том, как мои классы должны быть сопоставлены с сущностями хранилища таблиц Azure. Скажем, у меня есть две сущности, BikeRider и BikeRace. В моем коде C # у меня есть 2 класса, и каждый из них имеет свойство, являющееся коллекцией другого. Итак, у класса BikeRider есть свойство List, и наоборот. Если здесь это не идеально, не стесняйтесь высказывать свое мнение, но это то, что у меня есть сегодня.

Как это соотносится с таблицей Azure? Я нашел здесь вопросы по SO, в которых обсуждается, как хранить отношения «многие ко многим», но мой вопрос более конкретно заключается в том, как следует обрабатывать свойство List при сохранении объекта, содержащего это свойство.

Благодарность!

ОБНОВЛЕНИЕ Пока я ждал ответа на это (и думал, что могу его не получить), я придумал следующее решение:

Типы C # BikeRider и BikeRace имеют свойство List другого типа, как я описал выше. У каждого есть метод экземпляра для добавления экземпляра другого в свой список (например, у BikeRace есть метод под названием «AddBikeRider», который добавляет экземпляр BikeRider в список BikeRace.BikeRiders, и наоборот).

Однако, когда я сохраняю в хранилище таблиц Azure, есть 3 таблицы со следующей информацией:

Таблица BikeRider

  • PartitionKey, RowKey,

Информация о велосипеде RiderRace Таблица

  • PartitionKey: BikeRider RowKey
  • RowKey: BikeRace RowKey
  • Дополнительная информация

Таблица BikeRace

  • PartitionKey, RowKey
  • Отдельное значение для идентификатора каждого BikeRider в гонке (BikeRider RowKey - но может быть много).

Таким образом, если вы запрашиваете у BikeRider и пытаетесь получить BikeRaces, в которых он был, у вас есть ключ раздела, и все строки в этом разделе являются BikeRaces. Если вы запрашиваете из BikeRace и пытаетесь получить всех байкеров в гонке, у вас есть BikeRider ID, которые можно использовать при запросе таблицы BikeRider. Вы не дублируете данные, кроме хранения этих ключей в нескольких местах, поэтому вам не нужно хранить несколько мест, если ваши данные изменяются.

Проблема здесь в том, что опубликовал Ming: если метод сохранения Table Service вызывает исключение для типа со свойством List, можете ли вы создать более простой интерфейс с его собственным предварительным методом сохранения, который обрабатывает тип списка и превращает его в сохранение. способный тип данных, чтобы сохранить его в таблицах Azure, как я описал? Это слишком сложно или слишком хрупко?


person Andrew B Schultz    schedule 02.06.2012    source источник


Ответы (1)


это не поддерживается. Хранилище таблиц не поддерживает свойства списков. Если вы используете свойство списка в своей модели данных CLR, WCF Data Services попытается сериализовать его, что приведет к исключению.

Чтобы смоделировать связь, вы можете создать свойство для объекта BikeRace, например BikeRiderID.

Если вам нужна коллекция только для чтения, вы можете создать метод (вместо свойства) в классе BikeRider, например GetBikeRaces. Внутри реализации вы запрашиваете таблицу BikeRace, чтобы найти все объекты, у которых BikeRiderID является идентификатором текущего велосипедиста. Если вы хотите обновить список велогонок, вам также необходимо обновить таблицу BikeRider с помощью отдельного запроса.

Вы можете обратиться к http://blog.smarx.com/posts/one-to-many-relationships-in-windows-azure-tables для примера.

person Ming Xu - MSFT    schedule 04.06.2012
comment
Спасибо, Мин! Это полезно. Однако я на самом деле не хотел сохранять список в таблице, я просто хотел знать, как можно обрабатывать это свойство при сохранении. Я понимаю, что если у меня просто есть тип со свойством List ‹T›, производным от TableServiceEntity, вы говорите, что я получу исключение, когда попытаюсь сохранить любой экземпляр этого типа (правильно?). Однако есть ли способ обработать преобразование свойства List ‹T› до того, как экземпляры этого типа попадут в методы TableService во время сохранения? Я обновлю свой пост, чтобы показать, каким было мое решение до того, как вы написали этот ответ. - person Andrew B Schultz; 05.06.2012
comment
Если вы можете, попробуйте использовать метод вместо свойства, чтобы вы вообще не столкнулись с проблемой сериализации. Если вам нужно использовать свойство, вы можете обработать событие WritingRequest (msdn.microsoft.com/en-us/library/). Здесь вы можете использовать e.Content для получения сериализованного потока. вы можете изменить его и удалить список перед отправкой в ​​службу хранения таблиц. Однако это требует некоторой работы с необработанным xml. - person Ming Xu - MSFT; 05.06.2012